@authup/server-core 1.0.0-beta.62 → 1.0.0-beta.64

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 (769) hide show
  1. package/dist/adapters/database/data-source/options/module.d.ts +1 -0
  2. package/dist/adapters/database/data-source/options/module.d.ts.map +1 -1
  3. package/dist/adapters/database/data-source/options/module.mjs +33 -4
  4. package/dist/adapters/database/data-source/options/module.mjs.map +1 -1
  5. package/dist/adapters/database/domains/client/entity.d.ts +1 -2
  6. package/dist/adapters/database/domains/client/entity.d.ts.map +1 -1
  7. package/dist/adapters/database/domains/client/entity.mjs +7 -14
  8. package/dist/adapters/database/domains/client/entity.mjs.map +1 -1
  9. package/dist/adapters/database/domains/identity-provider-attribute/subscriber.d.ts +9 -1
  10. package/dist/adapters/database/domains/identity-provider-attribute/subscriber.d.ts.map +1 -1
  11. package/dist/adapters/database/domains/identity-provider-attribute/subscriber.mjs +14 -0
  12. package/dist/adapters/database/domains/identity-provider-attribute/subscriber.mjs.map +1 -1
  13. package/dist/adapters/database/domains/session/entity.d.ts +8 -0
  14. package/dist/adapters/database/domains/session/entity.d.ts.map +1 -1
  15. package/dist/adapters/database/domains/session/entity.mjs +19 -0
  16. package/dist/adapters/database/domains/session/entity.mjs.map +1 -1
  17. package/dist/adapters/database/domains/user/entity.d.ts +1 -0
  18. package/dist/adapters/database/domains/user/entity.d.ts.map +1 -1
  19. package/dist/adapters/database/domains/user/entity.mjs +6 -0
  20. package/dist/adapters/database/domains/user/entity.mjs.map +1 -1
  21. package/dist/adapters/database/extra-attribute-repository/repository.mjs +1 -1
  22. package/dist/adapters/database/extra-attribute-repository/repository.mjs.map +1 -1
  23. package/dist/adapters/database/extra-attribute-repository/tree/adapter.mjs +4 -2
  24. package/dist/adapters/database/extra-attribute-repository/tree/adapter.mjs.map +1 -1
  25. package/dist/adapters/database/extra-attribute-repository/tree/repository.mjs +1 -1
  26. package/dist/adapters/database/extra-attribute-repository/tree/repository.mjs.map +1 -1
  27. package/dist/adapters/database/index.mjs +3 -3
  28. package/dist/adapters/database/migrations/mysql/1787571998009-SessionUserAndClientColumns.d.ts +56 -0
  29. package/dist/adapters/database/migrations/mysql/1787571998009-SessionUserAndClientColumns.d.ts.map +1 -0
  30. package/dist/adapters/database/migrations/mysql/1787571998009-SessionUserAndClientColumns.mjs +105 -0
  31. package/dist/adapters/database/migrations/mysql/1787571998009-SessionUserAndClientColumns.mjs.map +1 -0
  32. package/dist/adapters/database/migrations/postgres/1787571998009-SessionUserAndClientColumns.d.ts +56 -0
  33. package/dist/adapters/database/migrations/postgres/1787571998009-SessionUserAndClientColumns.d.ts.map +1 -0
  34. package/dist/adapters/database/migrations/postgres/1787571998009-SessionUserAndClientColumns.mjs +104 -0
  35. package/dist/adapters/database/migrations/postgres/1787571998009-SessionUserAndClientColumns.mjs.map +1 -0
  36. package/dist/adapters/database/subscriber/module.d.ts +6 -2
  37. package/dist/adapters/database/subscriber/module.d.ts.map +1 -1
  38. package/dist/adapters/database/subscriber/module.mjs +9 -5
  39. package/dist/adapters/database/subscriber/module.mjs.map +1 -1
  40. package/dist/adapters/http/adapters/oauth2/authorization/module.mjs +1 -1
  41. package/dist/adapters/http/adapters/oauth2/authorization/module.mjs.map +1 -1
  42. package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.d.ts.map +1 -1
  43. package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.mjs +8 -2
  44. package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.mjs.map +1 -1
  45. package/dist/adapters/http/constants.d.ts +18 -0
  46. package/dist/adapters/http/constants.d.ts.map +1 -0
  47. package/dist/adapters/http/constants.mjs +23 -0
  48. package/dist/adapters/http/constants.mjs.map +1 -0
  49. package/dist/adapters/http/controllers/entities/client/module.mjs +1 -1
  50. package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts +23 -1
  51. package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts.map +1 -1
  52. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs +86 -47
  53. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs.map +1 -1
  54. package/dist/adapters/http/controllers/entities/identity-provider/types.d.ts +6 -0
  55. package/dist/adapters/http/controllers/entities/identity-provider/types.d.ts.map +1 -1
  56. package/dist/adapters/http/controllers/entities/realm/module.d.ts.map +1 -1
  57. package/dist/adapters/http/controllers/entities/realm/module.mjs +2 -0
  58. package/dist/adapters/http/controllers/entities/realm/module.mjs.map +1 -1
  59. package/dist/adapters/http/controllers/entities/session/module.d.ts +33 -1
  60. package/dist/adapters/http/controllers/entities/session/module.d.ts.map +1 -1
  61. package/dist/adapters/http/controllers/entities/session/module.mjs +74 -0
  62. package/dist/adapters/http/controllers/entities/session/module.mjs.map +1 -1
  63. package/dist/adapters/http/controllers/index.mjs +3 -1
  64. package/dist/adapters/http/controllers/workflows/account/index.d.ts +1 -0
  65. package/dist/adapters/http/controllers/workflows/account/index.d.ts.map +1 -1
  66. package/dist/adapters/http/controllers/workflows/account/module.d.ts +25 -16
  67. package/dist/adapters/http/controllers/workflows/account/module.d.ts.map +1 -1
  68. package/dist/adapters/http/controllers/workflows/account/module.mjs +40 -17
  69. package/dist/adapters/http/controllers/workflows/account/module.mjs.map +1 -1
  70. package/dist/adapters/http/controllers/workflows/account/types.d.ts +33 -0
  71. package/dist/adapters/http/controllers/workflows/account/types.d.ts.map +1 -0
  72. package/dist/adapters/http/controllers/workflows/activate/module.d.ts +8 -4
  73. package/dist/adapters/http/controllers/workflows/activate/module.d.ts.map +1 -1
  74. package/dist/adapters/http/controllers/workflows/activate/module.mjs +7 -9
  75. package/dist/adapters/http/controllers/workflows/activate/module.mjs.map +1 -1
  76. package/dist/adapters/http/controllers/workflows/admin/index.d.ts.map +1 -0
  77. package/dist/adapters/http/controllers/workflows/admin/index.mjs +5 -0
  78. package/dist/adapters/http/controllers/workflows/admin/module.d.ts +30 -0
  79. package/dist/adapters/http/controllers/workflows/admin/module.d.ts.map +1 -0
  80. package/dist/adapters/http/controllers/workflows/admin/module.mjs +88 -0
  81. package/dist/adapters/http/controllers/workflows/admin/module.mjs.map +1 -0
  82. package/dist/adapters/http/controllers/workflows/admin/types.d.ts +14 -0
  83. package/dist/adapters/http/controllers/workflows/admin/types.d.ts.map +1 -0
  84. package/dist/adapters/http/controllers/workflows/auth-console.d.ts +16 -0
  85. package/dist/adapters/http/controllers/workflows/auth-console.d.ts.map +1 -0
  86. package/dist/adapters/http/controllers/workflows/auth-console.mjs +32 -0
  87. package/dist/adapters/http/controllers/workflows/auth-console.mjs.map +1 -0
  88. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.d.ts +2 -0
  89. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.d.ts.map +1 -1
  90. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.mjs +21 -3
  91. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.mjs.map +1 -1
  92. package/dist/adapters/http/controllers/workflows/authorize/module.d.ts +16 -1
  93. package/dist/adapters/http/controllers/workflows/authorize/module.d.ts.map +1 -1
  94. package/dist/adapters/http/controllers/workflows/authorize/module.mjs +44 -21
  95. package/dist/adapters/http/controllers/workflows/authorize/module.mjs.map +1 -1
  96. package/dist/adapters/http/controllers/workflows/authorize/types.d.ts +5 -0
  97. package/dist/adapters/http/controllers/workflows/authorize/types.d.ts.map +1 -1
  98. package/dist/adapters/http/controllers/workflows/console-login/index.d.ts +3 -0
  99. package/dist/adapters/http/controllers/workflows/console-login/index.d.ts.map +1 -0
  100. package/dist/adapters/http/controllers/workflows/console-login/index.mjs +5 -0
  101. package/dist/adapters/http/controllers/workflows/console-login/module.d.ts +83 -0
  102. package/dist/adapters/http/controllers/workflows/console-login/module.d.ts.map +1 -0
  103. package/dist/adapters/http/controllers/workflows/console-login/module.mjs +230 -0
  104. package/dist/adapters/http/controllers/workflows/console-login/module.mjs.map +1 -0
  105. package/dist/adapters/http/controllers/workflows/console-login/types.d.ts +58 -0
  106. package/dist/adapters/http/controllers/workflows/console-login/types.d.ts.map +1 -0
  107. package/dist/adapters/http/controllers/workflows/index.d.ts +2 -0
  108. package/dist/adapters/http/controllers/workflows/index.d.ts.map +1 -1
  109. package/dist/adapters/http/controllers/workflows/index.mjs +5 -1
  110. package/dist/adapters/http/controllers/workflows/logout/module.d.ts +32 -3
  111. package/dist/adapters/http/controllers/workflows/logout/module.d.ts.map +1 -1
  112. package/dist/adapters/http/controllers/workflows/logout/module.mjs +48 -24
  113. package/dist/adapters/http/controllers/workflows/logout/module.mjs.map +1 -1
  114. package/dist/adapters/http/controllers/workflows/logout/types.d.ts +1 -1
  115. package/dist/adapters/http/controllers/workflows/logout/types.d.ts.map +1 -1
  116. package/dist/adapters/http/controllers/workflows/password-forgot/module.d.ts +8 -4
  117. package/dist/adapters/http/controllers/workflows/password-forgot/module.d.ts.map +1 -1
  118. package/dist/adapters/http/controllers/workflows/password-forgot/module.mjs +7 -9
  119. package/dist/adapters/http/controllers/workflows/password-forgot/module.mjs.map +1 -1
  120. package/dist/adapters/http/controllers/workflows/password-reset/module.d.ts +8 -4
  121. package/dist/adapters/http/controllers/workflows/password-reset/module.d.ts.map +1 -1
  122. package/dist/adapters/http/controllers/workflows/password-reset/module.mjs +7 -10
  123. package/dist/adapters/http/controllers/workflows/password-reset/module.mjs.map +1 -1
  124. package/dist/adapters/http/controllers/workflows/register/module.d.ts +8 -4
  125. package/dist/adapters/http/controllers/workflows/register/module.d.ts.map +1 -1
  126. package/dist/adapters/http/controllers/workflows/register/module.mjs +7 -9
  127. package/dist/adapters/http/controllers/workflows/register/module.mjs.map +1 -1
  128. package/dist/adapters/http/controllers/workflows/status/module.mjs +1 -1
  129. package/dist/adapters/http/controllers/workflows/token/module.d.ts +45 -2
  130. package/dist/adapters/http/controllers/workflows/token/module.d.ts.map +1 -1
  131. package/dist/adapters/http/controllers/workflows/token/module.mjs +117 -26
  132. package/dist/adapters/http/controllers/workflows/token/module.mjs.map +1 -1
  133. package/dist/adapters/http/cookie/index.d.ts +2 -0
  134. package/dist/adapters/http/cookie/index.d.ts.map +1 -0
  135. package/dist/adapters/http/cookie/index.mjs +5 -0
  136. package/dist/adapters/http/cookie/session.d.ts +35 -0
  137. package/dist/adapters/http/cookie/session.d.ts.map +1 -0
  138. package/dist/adapters/http/cookie/session.mjs +62 -0
  139. package/dist/adapters/http/cookie/session.mjs.map +1 -0
  140. package/dist/adapters/http/index.d.ts +2 -0
  141. package/dist/adapters/http/index.d.ts.map +1 -1
  142. package/dist/adapters/http/index.mjs +20 -16
  143. package/dist/adapters/http/internal-client/index.d.ts +3 -0
  144. package/dist/adapters/http/internal-client/index.d.ts.map +1 -0
  145. package/dist/adapters/http/internal-client/index.mjs +5 -0
  146. package/dist/adapters/http/internal-client/module.d.ts +21 -0
  147. package/dist/adapters/http/internal-client/module.d.ts.map +1 -0
  148. package/dist/adapters/http/{ui/auth-console/http-client.mjs → internal-client/module.mjs} +16 -15
  149. package/dist/adapters/http/internal-client/module.mjs.map +1 -0
  150. package/dist/adapters/http/internal-client/types.d.ts +13 -0
  151. package/dist/adapters/http/internal-client/types.d.ts.map +1 -0
  152. package/dist/adapters/http/middleware/built-in/authorization/index.d.ts +1 -0
  153. package/dist/adapters/http/middleware/built-in/authorization/index.d.ts.map +1 -1
  154. package/dist/adapters/http/middleware/built-in/authorization/index.mjs +2 -1
  155. package/dist/adapters/http/middleware/built-in/authorization/issuance.d.ts +45 -0
  156. package/dist/adapters/http/middleware/built-in/authorization/issuance.d.ts.map +1 -0
  157. package/dist/adapters/http/middleware/built-in/authorization/issuance.mjs +61 -0
  158. package/dist/adapters/http/middleware/built-in/authorization/issuance.mjs.map +1 -0
  159. package/dist/adapters/http/middleware/built-in/authorization/module.d.ts +26 -2
  160. package/dist/adapters/http/middleware/built-in/authorization/module.d.ts.map +1 -1
  161. package/dist/adapters/http/middleware/built-in/authorization/module.mjs +67 -1
  162. package/dist/adapters/http/middleware/built-in/authorization/module.mjs.map +1 -1
  163. package/dist/adapters/http/middleware/built-in/authorization/types.d.ts +21 -1
  164. package/dist/adapters/http/middleware/built-in/authorization/types.d.ts.map +1 -1
  165. package/dist/adapters/http/middleware/built-in/basic.d.ts +2 -2
  166. package/dist/adapters/http/middleware/built-in/basic.d.ts.map +1 -1
  167. package/dist/adapters/http/middleware/built-in/basic.mjs.map +1 -1
  168. package/dist/adapters/http/middleware/built-in/cors.d.ts +8 -2
  169. package/dist/adapters/http/middleware/built-in/cors.d.ts.map +1 -1
  170. package/dist/adapters/http/middleware/built-in/cors.mjs +20 -3
  171. package/dist/adapters/http/middleware/built-in/cors.mjs.map +1 -1
  172. package/dist/adapters/http/middleware/built-in/error.d.ts +2 -2
  173. package/dist/adapters/http/middleware/built-in/error.d.ts.map +1 -1
  174. package/dist/adapters/http/middleware/built-in/error.mjs +10 -1
  175. package/dist/adapters/http/middleware/built-in/error.mjs.map +1 -1
  176. package/dist/adapters/http/middleware/built-in/index.d.ts +1 -4
  177. package/dist/adapters/http/middleware/built-in/index.d.ts.map +1 -1
  178. package/dist/adapters/http/middleware/built-in/index.mjs +3 -4
  179. package/dist/adapters/http/middleware/built-in/internal-http-client.d.ts +17 -0
  180. package/dist/adapters/http/middleware/built-in/internal-http-client.d.ts.map +1 -0
  181. package/dist/adapters/http/middleware/built-in/internal-http-client.mjs +27 -0
  182. package/dist/adapters/http/middleware/built-in/internal-http-client.mjs.map +1 -0
  183. package/dist/adapters/http/middleware/built-in/logger.mjs +1 -1
  184. package/dist/adapters/http/middleware/built-in/logger.mjs.map +1 -1
  185. package/dist/adapters/http/middleware/built-in/prometheus.d.ts +6 -5
  186. package/dist/adapters/http/middleware/built-in/prometheus.d.ts.map +1 -1
  187. package/dist/adapters/http/middleware/built-in/prometheus.mjs +3 -2
  188. package/dist/adapters/http/middleware/built-in/prometheus.mjs.map +1 -1
  189. package/dist/adapters/http/middleware/built-in/rate-limit.d.ts +2 -2
  190. package/dist/adapters/http/middleware/built-in/rate-limit.d.ts.map +1 -1
  191. package/dist/adapters/http/middleware/built-in/rate-limit.mjs +15 -0
  192. package/dist/adapters/http/middleware/built-in/rate-limit.mjs.map +1 -1
  193. package/dist/adapters/http/middleware/index.mjs +3 -4
  194. package/dist/adapters/http/request/constants.d.ts +1 -1
  195. package/dist/adapters/http/request/constants.d.ts.map +1 -1
  196. package/dist/adapters/http/request/constants.mjs +1 -5
  197. package/dist/adapters/http/request/constants.mjs.map +1 -1
  198. package/dist/adapters/http/request/helpers/index.d.ts +1 -1
  199. package/dist/adapters/http/request/helpers/index.d.ts.map +1 -1
  200. package/dist/adapters/http/request/helpers/index.mjs +2 -2
  201. package/dist/adapters/http/request/helpers/locale.d.ts +2 -1
  202. package/dist/adapters/http/request/helpers/locale.d.ts.map +1 -1
  203. package/dist/adapters/http/request/helpers/locale.mjs +1 -1
  204. package/dist/adapters/http/request/helpers/locale.mjs.map +1 -1
  205. package/dist/adapters/http/request/helpers/same-origin.d.ts +38 -0
  206. package/dist/adapters/http/request/helpers/same-origin.d.ts.map +1 -0
  207. package/dist/adapters/http/request/helpers/same-origin.mjs +68 -0
  208. package/dist/adapters/http/request/helpers/same-origin.mjs.map +1 -0
  209. package/dist/adapters/http/request/index.mjs +2 -2
  210. package/dist/adapters/http/request/permission/module.mjs +1 -1
  211. package/dist/adapters/http/request/permission/module.mjs.map +1 -1
  212. package/dist/adapters/http/request/types.d.ts +1 -2
  213. package/dist/adapters/http/request/types.d.ts.map +1 -1
  214. package/dist/adapters/shared/ldap/module.d.ts.map +1 -1
  215. package/dist/adapters/shared/ldap/module.mjs +4 -1
  216. package/dist/adapters/shared/ldap/module.mjs.map +1 -1
  217. package/dist/app/builder.d.ts +4 -4
  218. package/dist/app/builder.d.ts.map +1 -1
  219. package/dist/app/builder.mjs +7 -4
  220. package/dist/app/builder.mjs.map +1 -1
  221. package/dist/app/factory.d.ts +10 -0
  222. package/dist/app/factory.d.ts.map +1 -1
  223. package/dist/app/factory.mjs +26 -2
  224. package/dist/app/factory.mjs.map +1 -1
  225. package/dist/app/index.mjs +17 -19
  226. package/dist/app/modules/authentication/module.d.ts.map +1 -1
  227. package/dist/app/modules/authentication/module.mjs +15 -2
  228. package/dist/app/modules/authentication/module.mjs.map +1 -1
  229. package/dist/app/modules/authentication/repositories/session.d.ts +4 -1
  230. package/dist/app/modules/authentication/repositories/session.d.ts.map +1 -1
  231. package/dist/app/modules/authentication/repositories/session.mjs +20 -3
  232. package/dist/app/modules/authentication/repositories/session.mjs.map +1 -1
  233. package/dist/app/modules/components/index.d.ts +1 -0
  234. package/dist/app/modules/components/index.d.ts.map +1 -1
  235. package/dist/app/modules/components/module.d.ts +3 -1
  236. package/dist/app/modules/components/module.d.ts.map +1 -1
  237. package/dist/app/modules/components/module.mjs +26 -7
  238. package/dist/app/modules/components/module.mjs.map +1 -1
  239. package/dist/app/modules/components/types.d.ts +11 -0
  240. package/dist/app/modules/components/types.d.ts.map +1 -0
  241. package/dist/app/modules/config/app-origins.d.ts +10 -0
  242. package/dist/app/modules/config/app-origins.d.ts.map +1 -0
  243. package/dist/app/modules/config/app-origins.mjs +21 -0
  244. package/dist/app/modules/config/app-origins.mjs.map +1 -0
  245. package/dist/app/modules/config/constants.d.ts +23 -50
  246. package/dist/app/modules/config/constants.d.ts.map +1 -1
  247. package/dist/app/modules/config/constants.mjs +34 -51
  248. package/dist/app/modules/config/constants.mjs.map +1 -1
  249. package/dist/app/modules/config/index.d.ts +2 -3
  250. package/dist/app/modules/config/index.d.ts.map +1 -1
  251. package/dist/app/modules/config/index.mjs +4 -8
  252. package/dist/app/modules/config/module.d.ts +2 -2
  253. package/dist/app/modules/config/module.d.ts.map +1 -1
  254. package/dist/app/modules/config/module.mjs +1 -1
  255. package/dist/app/modules/config/module.mjs.map +1 -1
  256. package/dist/app/modules/config/read.d.ts +29 -0
  257. package/dist/app/modules/config/read.d.ts.map +1 -0
  258. package/dist/app/modules/config/read.mjs +65 -0
  259. package/dist/app/modules/config/read.mjs.map +1 -0
  260. package/dist/app/modules/config/types.d.ts +30 -397
  261. package/dist/app/modules/config/types.d.ts.map +1 -1
  262. package/dist/app/modules/config/validator.d.ts.map +1 -1
  263. package/dist/app/modules/config/validator.mjs +3 -87
  264. package/dist/app/modules/config/validator.mjs.map +1 -1
  265. package/dist/app/modules/database/index.d.ts +1 -0
  266. package/dist/app/modules/database/index.d.ts.map +1 -1
  267. package/dist/app/modules/database/index.mjs +2 -1
  268. package/dist/app/modules/database/migration.d.ts +33 -0
  269. package/dist/app/modules/database/migration.d.ts.map +1 -0
  270. package/dist/app/modules/database/migration.mjs +52 -0
  271. package/dist/app/modules/database/migration.mjs.map +1 -0
  272. package/dist/app/modules/database/module.d.ts.map +1 -1
  273. package/dist/app/modules/database/module.mjs +12 -6
  274. package/dist/app/modules/database/module.mjs.map +1 -1
  275. package/dist/app/modules/database/repositories/client/repository.d.ts +6 -1
  276. package/dist/app/modules/database/repositories/client/repository.d.ts.map +1 -1
  277. package/dist/app/modules/database/repositories/client/repository.mjs +21 -4
  278. package/dist/app/modules/database/repositories/client/repository.mjs.map +1 -1
  279. package/dist/app/modules/database/repositories/event/repository.d.ts +29 -2
  280. package/dist/app/modules/database/repositories/event/repository.d.ts.map +1 -1
  281. package/dist/app/modules/database/repositories/event/repository.mjs +42 -24
  282. package/dist/app/modules/database/repositories/event/repository.mjs.map +1 -1
  283. package/dist/app/modules/database/repositories/helpers.d.ts +24 -1
  284. package/dist/app/modules/database/repositories/helpers.d.ts.map +1 -1
  285. package/dist/app/modules/database/repositories/helpers.mjs +38 -1
  286. package/dist/app/modules/database/repositories/helpers.mjs.map +1 -1
  287. package/dist/app/modules/database/repositories/identity-provider/repository.d.ts +3 -1
  288. package/dist/app/modules/database/repositories/identity-provider/repository.d.ts.map +1 -1
  289. package/dist/app/modules/database/repositories/identity-provider/repository.mjs +3 -3
  290. package/dist/app/modules/database/repositories/identity-provider/repository.mjs.map +1 -1
  291. package/dist/app/modules/database/repositories/identity-provider-account/repository.mjs +4 -2
  292. package/dist/app/modules/database/repositories/identity-provider-account/repository.mjs.map +1 -1
  293. package/dist/app/modules/database/repositories/key/repository.mjs +1 -1
  294. package/dist/app/modules/database/repositories/permission/repository.mjs +1 -1
  295. package/dist/app/modules/database/repositories/policy/repository.mjs +1 -1
  296. package/dist/app/modules/database/repositories/role/repository.mjs +1 -1
  297. package/dist/app/modules/database/repositories/scope/repository.mjs +1 -1
  298. package/dist/app/modules/database/repositories/trust-anchor/repository.mjs +1 -1
  299. package/dist/app/modules/database/repositories/user/repository.d.ts +7 -2
  300. package/dist/app/modules/database/repositories/user/repository.d.ts.map +1 -1
  301. package/dist/app/modules/database/repositories/user/repository.mjs +21 -4
  302. package/dist/app/modules/database/repositories/user/repository.mjs.map +1 -1
  303. package/dist/app/modules/http/constants.d.ts +3 -1
  304. package/dist/app/modules/http/constants.d.ts.map +1 -1
  305. package/dist/app/modules/http/constants.mjs +3 -2
  306. package/dist/app/modules/http/constants.mjs.map +1 -1
  307. package/dist/app/modules/http/module.d.ts +30 -9
  308. package/dist/app/modules/http/module.d.ts.map +1 -1
  309. package/dist/app/modules/http/module.mjs +31 -33
  310. package/dist/app/modules/http/module.mjs.map +1 -1
  311. package/dist/app/modules/http/modules/controller.d.ts +4 -3
  312. package/dist/app/modules/http/modules/controller.d.ts.map +1 -1
  313. package/dist/app/modules/http/modules/controller.mjs +70 -38
  314. package/dist/app/modules/http/modules/controller.mjs.map +1 -1
  315. package/dist/app/modules/http/modules/middleware.d.ts +13 -22
  316. package/dist/app/modules/http/modules/middleware.d.ts.map +1 -1
  317. package/dist/app/modules/http/modules/middleware.mjs +20 -36
  318. package/dist/app/modules/http/modules/middleware.mjs.map +1 -1
  319. package/dist/app/modules/identity/module.mjs +4 -4
  320. package/dist/app/modules/identity/repositories/client.mjs +4 -2
  321. package/dist/app/modules/identity/repositories/client.mjs.map +1 -1
  322. package/dist/app/modules/identity/repositories/user.mjs +4 -2
  323. package/dist/app/modules/identity/repositories/user.mjs.map +1 -1
  324. package/dist/app/modules/index.mjs +21 -23
  325. package/dist/app/modules/logger/module.mjs +1 -1
  326. package/dist/app/modules/logger/module.mjs.map +1 -1
  327. package/dist/app/modules/mail/module.d.ts.map +1 -1
  328. package/dist/app/modules/mail/module.mjs.map +1 -1
  329. package/dist/app/modules/oauth2/constants.d.ts +3 -1
  330. package/dist/app/modules/oauth2/constants.d.ts.map +1 -1
  331. package/dist/app/modules/oauth2/constants.mjs +2 -0
  332. package/dist/app/modules/oauth2/constants.mjs.map +1 -1
  333. package/dist/app/modules/oauth2/module.d.ts.map +1 -1
  334. package/dist/app/modules/oauth2/module.mjs +14 -4
  335. package/dist/app/modules/oauth2/module.mjs.map +1 -1
  336. package/dist/app/modules/oauth2/repositories/client/repository.mjs +4 -2
  337. package/dist/app/modules/oauth2/repositories/client/repository.mjs.map +1 -1
  338. package/dist/app/modules/oauth2/repositories/consent/repository.d.ts.map +1 -1
  339. package/dist/app/modules/oauth2/repositories/consent/repository.mjs +3 -2
  340. package/dist/app/modules/oauth2/repositories/consent/repository.mjs.map +1 -1
  341. package/dist/app/modules/oauth2/repositories/console-login/index.d.ts +2 -0
  342. package/dist/app/modules/oauth2/repositories/console-login/index.d.ts.map +1 -0
  343. package/dist/app/modules/oauth2/repositories/console-login/index.mjs +5 -0
  344. package/dist/app/modules/oauth2/repositories/console-login/store.d.ts +19 -0
  345. package/dist/app/modules/oauth2/repositories/console-login/store.d.ts.map +1 -0
  346. package/dist/app/modules/oauth2/repositories/console-login/store.mjs +47 -0
  347. package/dist/app/modules/oauth2/repositories/console-login/store.mjs.map +1 -0
  348. package/dist/app/modules/oauth2/repositories/constants.d.ts +2 -0
  349. package/dist/app/modules/oauth2/repositories/constants.d.ts.map +1 -1
  350. package/dist/app/modules/oauth2/repositories/constants.mjs +2 -0
  351. package/dist/app/modules/oauth2/repositories/constants.mjs.map +1 -1
  352. package/dist/app/modules/oauth2/repositories/federated-login/index.d.ts +2 -0
  353. package/dist/app/modules/oauth2/repositories/federated-login/index.d.ts.map +1 -0
  354. package/dist/app/modules/oauth2/repositories/federated-login/index.mjs +5 -0
  355. package/dist/app/modules/oauth2/repositories/federated-login/store.d.ts +9 -0
  356. package/dist/app/modules/oauth2/repositories/federated-login/store.d.ts.map +1 -0
  357. package/dist/app/modules/oauth2/repositories/federated-login/store.mjs +33 -0
  358. package/dist/app/modules/oauth2/repositories/federated-login/store.mjs.map +1 -0
  359. package/dist/app/modules/oauth2/repositories/index.d.ts +2 -0
  360. package/dist/app/modules/oauth2/repositories/index.d.ts.map +1 -1
  361. package/dist/app/modules/oauth2/repositories/index.mjs +5 -1
  362. package/dist/app/modules/oauth2/repositories/session-token/repository.d.ts +2 -2
  363. package/dist/app/modules/oauth2/repositories/session-token/repository.d.ts.map +1 -1
  364. package/dist/app/modules/oauth2/repositories/session-token/repository.mjs +5 -3
  365. package/dist/app/modules/oauth2/repositories/session-token/repository.mjs.map +1 -1
  366. package/dist/app/modules/provisioning/module.d.ts.map +1 -1
  367. package/dist/app/modules/provisioning/module.mjs +5 -6
  368. package/dist/app/modules/provisioning/module.mjs.map +1 -1
  369. package/dist/app/modules/provisioning/sources/composite/module.d.ts.map +1 -1
  370. package/dist/app/modules/provisioning/sources/composite/module.mjs +2 -1
  371. package/dist/app/modules/provisioning/sources/composite/module.mjs.map +1 -1
  372. package/dist/app/modules/provisioning/sources/default/module.d.ts.map +1 -1
  373. package/dist/app/modules/provisioning/sources/default/module.mjs +2 -1
  374. package/dist/app/modules/provisioning/sources/default/module.mjs.map +1 -1
  375. package/dist/app/modules/runtime/module.d.ts.map +1 -1
  376. package/dist/app/modules/runtime/module.mjs +2 -1
  377. package/dist/app/modules/runtime/module.mjs.map +1 -1
  378. package/dist/app/types.d.ts +16 -0
  379. package/dist/app/types.d.ts.map +1 -1
  380. package/dist/cli/commands/config.d.ts +40 -0
  381. package/dist/cli/commands/config.d.ts.map +1 -0
  382. package/dist/cli/commands/config.mjs +65 -0
  383. package/dist/cli/commands/config.mjs.map +1 -0
  384. package/dist/cli/commands/healthcheck.d.ts +3 -2
  385. package/dist/cli/commands/healthcheck.d.ts.map +1 -1
  386. package/dist/cli/commands/healthcheck.mjs +6 -3
  387. package/dist/cli/commands/healthcheck.mjs.map +1 -1
  388. package/dist/cli/commands/index.d.ts +3 -0
  389. package/dist/cli/commands/index.d.ts.map +1 -1
  390. package/dist/cli/commands/index.mjs +3 -1
  391. package/dist/cli/commands/migration.d.ts +3 -10
  392. package/dist/cli/commands/migration.d.ts.map +1 -1
  393. package/dist/cli/commands/migration.mjs +17 -9
  394. package/dist/cli/commands/migration.mjs.map +1 -1
  395. package/dist/cli/commands/shutdown.d.ts +16 -0
  396. package/dist/cli/commands/shutdown.d.ts.map +1 -0
  397. package/dist/cli/commands/shutdown.mjs +41 -0
  398. package/dist/cli/commands/shutdown.mjs.map +1 -0
  399. package/dist/cli/commands/start.d.ts +3 -2
  400. package/dist/cli/commands/start.d.ts.map +1 -1
  401. package/dist/cli/commands/start.mjs +3 -21
  402. package/dist/cli/commands/start.mjs.map +1 -1
  403. package/dist/cli/commands/types.d.ts.map +1 -0
  404. package/dist/cli/index.d.ts +8 -0
  405. package/dist/cli/index.d.ts.map +1 -1
  406. package/dist/cli/index.mjs.map +1 -1
  407. package/dist/cli/module.d.ts +0 -2
  408. package/dist/cli/module.d.ts.map +1 -1
  409. package/dist/cli/module.mjs +4 -3
  410. package/dist/cli/module.mjs.map +1 -1
  411. package/dist/components/oauth2-cleaner/module.d.ts +2 -2
  412. package/dist/components/oauth2-cleaner/module.d.ts.map +1 -1
  413. package/dist/components/oauth2-cleaner/module.mjs +10 -7
  414. package/dist/components/oauth2-cleaner/module.mjs.map +1 -1
  415. package/dist/core/authentication/index.mjs +2 -1
  416. package/dist/core/authentication/session/constants.d.ts +10 -0
  417. package/dist/core/authentication/session/constants.d.ts.map +1 -0
  418. package/dist/core/authentication/session/constants.mjs +16 -0
  419. package/dist/core/authentication/session/constants.mjs.map +1 -0
  420. package/dist/core/authentication/session/index.d.ts +1 -0
  421. package/dist/core/authentication/session/index.d.ts.map +1 -1
  422. package/dist/core/authentication/session/index.mjs +2 -1
  423. package/dist/core/authentication/session/module.d.ts +2 -1
  424. package/dist/core/authentication/session/module.d.ts.map +1 -1
  425. package/dist/core/authentication/session/module.mjs +7 -1
  426. package/dist/core/authentication/session/module.mjs.map +1 -1
  427. package/dist/core/authentication/session/types.d.ts +70 -1
  428. package/dist/core/authentication/session/types.d.ts.map +1 -1
  429. package/dist/core/authentication/session/types.mjs.map +1 -1
  430. package/dist/core/entities/client/schema.d.ts.map +1 -1
  431. package/dist/core/entities/client/schema.mjs +1 -2
  432. package/dist/core/entities/client/schema.mjs.map +1 -1
  433. package/dist/core/entities/client/service.d.ts.map +1 -1
  434. package/dist/core/entities/client/service.mjs +15 -1
  435. package/dist/core/entities/client/service.mjs.map +1 -1
  436. package/dist/core/entities/client/system-clients.d.ts +0 -5
  437. package/dist/core/entities/client/system-clients.d.ts.map +1 -1
  438. package/dist/core/entities/client/system-clients.mjs +0 -6
  439. package/dist/core/entities/client/system-clients.mjs.map +1 -1
  440. package/dist/core/entities/client/types.d.ts +12 -0
  441. package/dist/core/entities/client/types.d.ts.map +1 -1
  442. package/dist/core/entities/client-permission/service.mjs +1 -1
  443. package/dist/core/entities/client-permission/service.mjs.map +1 -1
  444. package/dist/core/entities/event/constants.d.ts +1 -6
  445. package/dist/core/entities/event/constants.d.ts.map +1 -1
  446. package/dist/core/entities/event/constants.mjs +1 -5
  447. package/dist/core/entities/event/constants.mjs.map +1 -1
  448. package/dist/core/entities/event/entity-event-handler.d.ts.map +1 -1
  449. package/dist/core/entities/event/entity-event-handler.mjs +17 -3
  450. package/dist/core/entities/event/entity-event-handler.mjs.map +1 -1
  451. package/dist/core/entities/event/service.d.ts.map +1 -1
  452. package/dist/core/entities/event/service.mjs +3 -3
  453. package/dist/core/entities/event/service.mjs.map +1 -1
  454. package/dist/core/entities/event/types.d.ts +15 -1
  455. package/dist/core/entities/event/types.d.ts.map +1 -1
  456. package/dist/core/entities/identity-provider/types.d.ts +9 -1
  457. package/dist/core/entities/identity-provider/types.d.ts.map +1 -1
  458. package/dist/core/entities/permission/service.mjs +1 -2
  459. package/dist/core/entities/permission/service.mjs.map +1 -1
  460. package/dist/core/entities/role-permission/service.mjs +1 -1
  461. package/dist/core/entities/role-permission/service.mjs.map +1 -1
  462. package/dist/core/entities/session/service.d.ts +13 -1
  463. package/dist/core/entities/session/service.d.ts.map +1 -1
  464. package/dist/core/entities/session/service.mjs +19 -16
  465. package/dist/core/entities/session/service.mjs.map +1 -1
  466. package/dist/core/entities/user/schema.d.ts.map +1 -1
  467. package/dist/core/entities/user/schema.mjs +1 -0
  468. package/dist/core/entities/user/schema.mjs.map +1 -1
  469. package/dist/core/entities/user/service.d.ts.map +1 -1
  470. package/dist/core/entities/user/service.mjs +21 -1
  471. package/dist/core/entities/user/service.mjs.map +1 -1
  472. package/dist/core/entities/user/types.d.ts +12 -0
  473. package/dist/core/entities/user/types.d.ts.map +1 -1
  474. package/dist/core/entities/user-permission/service.mjs +1 -1
  475. package/dist/core/entities/user-permission/service.mjs.map +1 -1
  476. package/dist/core/identity/index.mjs +2 -1
  477. package/dist/core/identity/permission/junction-grant.mjs +1 -1
  478. package/dist/core/identity/permission/junction-grant.mjs.map +1 -1
  479. package/dist/core/identity/provider/account/module.mjs +2 -2
  480. package/dist/core/identity/provider/account/module.mjs.map +1 -1
  481. package/dist/core/identity/provider/authentication/index.mjs +2 -1
  482. package/dist/core/identity/provider/authentication/protocols/index.mjs +2 -1
  483. package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.d.ts +46 -0
  484. package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.d.ts.map +1 -0
  485. package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.mjs +89 -0
  486. package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.mjs.map +1 -0
  487. package/dist/core/identity/provider/authentication/protocols/oauth2/index.d.ts +1 -0
  488. package/dist/core/identity/provider/authentication/protocols/oauth2/index.d.ts.map +1 -1
  489. package/dist/core/identity/provider/authentication/protocols/oauth2/index.mjs +2 -1
  490. package/dist/core/identity/provider/authentication/protocols/oauth2/module.d.ts.map +1 -1
  491. package/dist/core/identity/provider/authentication/protocols/oauth2/module.mjs +9 -2
  492. package/dist/core/identity/provider/authentication/protocols/oauth2/module.mjs.map +1 -1
  493. package/dist/core/identity/provider/index.mjs +2 -1
  494. package/dist/core/identity/registration/service.d.ts.map +1 -1
  495. package/dist/core/identity/registration/service.mjs +2 -1
  496. package/dist/core/identity/registration/service.mjs.map +1 -1
  497. package/dist/core/index.mjs +14 -4
  498. package/dist/core/oauth2/authorization/helpers.d.ts +14 -0
  499. package/dist/core/oauth2/authorization/helpers.d.ts.map +1 -1
  500. package/dist/core/oauth2/authorization/helpers.mjs +15 -2
  501. package/dist/core/oauth2/authorization/helpers.mjs.map +1 -1
  502. package/dist/core/oauth2/authorization/index.mjs +2 -2
  503. package/dist/core/oauth2/authorization/module.d.ts.map +1 -1
  504. package/dist/core/oauth2/authorization/module.mjs +6 -4
  505. package/dist/core/oauth2/authorization/module.mjs.map +1 -1
  506. package/dist/core/oauth2/authorization/state/types.d.ts +8 -0
  507. package/dist/core/oauth2/authorization/state/types.d.ts.map +1 -1
  508. package/dist/core/oauth2/backchannel-logout/constants.d.ts +16 -0
  509. package/dist/core/oauth2/backchannel-logout/constants.d.ts.map +1 -0
  510. package/dist/core/oauth2/backchannel-logout/constants.mjs +20 -0
  511. package/dist/core/oauth2/backchannel-logout/constants.mjs.map +1 -0
  512. package/dist/core/oauth2/backchannel-logout/index.d.ts +4 -0
  513. package/dist/core/oauth2/backchannel-logout/index.d.ts.map +1 -0
  514. package/dist/core/oauth2/backchannel-logout/index.mjs +6 -0
  515. package/dist/core/oauth2/backchannel-logout/module.d.ts +26 -0
  516. package/dist/core/oauth2/backchannel-logout/module.d.ts.map +1 -0
  517. package/dist/core/oauth2/backchannel-logout/module.mjs +78 -0
  518. package/dist/core/oauth2/backchannel-logout/module.mjs.map +1 -0
  519. package/dist/core/oauth2/backchannel-logout/types.d.ts +29 -0
  520. package/dist/core/oauth2/backchannel-logout/types.d.ts.map +1 -0
  521. package/dist/core/oauth2/console-login/constants.d.ts +19 -0
  522. package/dist/core/oauth2/console-login/constants.d.ts.map +1 -0
  523. package/dist/core/oauth2/console-login/constants.mjs +24 -0
  524. package/dist/core/oauth2/console-login/constants.mjs.map +1 -0
  525. package/dist/core/oauth2/console-login/index.d.ts +3 -0
  526. package/dist/core/oauth2/console-login/index.d.ts.map +1 -0
  527. package/dist/core/oauth2/console-login/index.mjs +5 -0
  528. package/dist/core/oauth2/console-login/types.d.ts +53 -0
  529. package/dist/core/oauth2/console-login/types.d.ts.map +1 -0
  530. package/dist/core/oauth2/end-session/service.mjs +1 -1
  531. package/dist/core/oauth2/end-session/service.mjs.map +1 -1
  532. package/dist/core/oauth2/federated-login/constants.d.ts +22 -0
  533. package/dist/core/oauth2/federated-login/constants.d.ts.map +1 -0
  534. package/dist/core/oauth2/federated-login/constants.mjs +27 -0
  535. package/dist/core/oauth2/federated-login/constants.mjs.map +1 -0
  536. package/dist/core/oauth2/federated-login/index.d.ts +1 -0
  537. package/dist/core/oauth2/federated-login/index.d.ts.map +1 -1
  538. package/dist/core/oauth2/federated-login/index.mjs +2 -1
  539. package/dist/core/oauth2/federated-login/module.d.ts +12 -3
  540. package/dist/core/oauth2/federated-login/module.d.ts.map +1 -1
  541. package/dist/core/oauth2/federated-login/module.mjs +98 -42
  542. package/dist/core/oauth2/federated-login/module.mjs.map +1 -1
  543. package/dist/core/oauth2/federated-login/types.d.ts +82 -24
  544. package/dist/core/oauth2/federated-login/types.d.ts.map +1 -1
  545. package/dist/core/oauth2/federated-login/types.mjs +5 -0
  546. package/dist/core/oauth2/federated-login/types.mjs.map +1 -1
  547. package/dist/core/oauth2/grant-types/authorize.mjs +1 -1
  548. package/dist/core/oauth2/grant-types/client-credentials.mjs +1 -1
  549. package/dist/core/oauth2/grant-types/identity.mjs +1 -1
  550. package/dist/core/oauth2/grant-types/password.mjs +1 -1
  551. package/dist/core/oauth2/grant-types/refresh-token.mjs +1 -1
  552. package/dist/core/oauth2/index.d.ts +4 -0
  553. package/dist/core/oauth2/index.d.ts.map +1 -1
  554. package/dist/core/oauth2/index.mjs +15 -4
  555. package/dist/core/oauth2/introspection/index.d.ts +3 -0
  556. package/dist/core/oauth2/introspection/index.d.ts.map +1 -0
  557. package/dist/core/oauth2/introspection/index.mjs +5 -0
  558. package/dist/core/oauth2/introspection/module.d.ts +14 -0
  559. package/dist/core/oauth2/introspection/module.d.ts.map +1 -0
  560. package/dist/core/oauth2/introspection/module.mjs +49 -0
  561. package/dist/core/oauth2/introspection/module.mjs.map +1 -0
  562. package/dist/core/oauth2/introspection/types.d.ts +45 -0
  563. package/dist/core/oauth2/introspection/types.d.ts.map +1 -0
  564. package/dist/core/oauth2/introspection/types.mjs +4 -0
  565. package/dist/core/oauth2/openid/claims.d.ts +20 -2
  566. package/dist/core/oauth2/openid/claims.d.ts.map +1 -1
  567. package/dist/core/oauth2/openid/claims.mjs +18 -4
  568. package/dist/core/oauth2/openid/claims.mjs.map +1 -1
  569. package/dist/core/oauth2/session-credential/constants.d.ts +30 -0
  570. package/dist/core/oauth2/session-credential/constants.d.ts.map +1 -0
  571. package/dist/core/oauth2/session-credential/constants.mjs +34 -0
  572. package/dist/core/oauth2/session-credential/constants.mjs.map +1 -0
  573. package/dist/core/oauth2/session-credential/index.d.ts +3 -0
  574. package/dist/core/oauth2/session-credential/index.d.ts.map +1 -0
  575. package/dist/core/oauth2/session-credential/index.mjs +6 -0
  576. package/dist/core/oauth2/session-credential/module.d.ts +31 -0
  577. package/dist/core/oauth2/session-credential/module.d.ts.map +1 -0
  578. package/dist/core/oauth2/session-credential/module.mjs +43 -0
  579. package/dist/core/oauth2/session-credential/module.mjs.map +1 -0
  580. package/dist/core/oauth2/session-token/constants.d.ts +10 -0
  581. package/dist/core/oauth2/session-token/constants.d.ts.map +1 -0
  582. package/dist/core/oauth2/session-token/constants.mjs +16 -0
  583. package/dist/core/oauth2/session-token/constants.mjs.map +1 -0
  584. package/dist/core/oauth2/session-token/index.d.ts +1 -0
  585. package/dist/core/oauth2/session-token/index.d.ts.map +1 -1
  586. package/dist/core/oauth2/session-token/index.mjs +2 -1
  587. package/dist/core/oauth2/session-token/types.d.ts +13 -2
  588. package/dist/core/oauth2/session-token/types.d.ts.map +1 -1
  589. package/dist/core/oauth2/token/verifier/module.d.ts.map +1 -1
  590. package/dist/core/oauth2/token/verifier/module.mjs +3 -3
  591. package/dist/core/oauth2/token/verifier/module.mjs.map +1 -1
  592. package/dist/core/provisioning/merge/module.mjs +5 -3
  593. package/dist/core/provisioning/merge/module.mjs.map +1 -1
  594. package/dist/core/query/module.mjs +1 -1
  595. package/dist/core/query/module.mjs.map +1 -1
  596. package/dist/core/security/policy/evaluator.mjs +1 -1
  597. package/dist/core/security/policy/evaluator.mjs.map +1 -1
  598. package/dist/index.mjs +62 -59
  599. package/dist/path.mjs +1 -1
  600. package/dist/swagger.json +573 -163
  601. package/dist/utils/error.d.ts +6 -0
  602. package/dist/utils/error.d.ts.map +1 -1
  603. package/dist/utils/error.mjs +6 -2
  604. package/dist/utils/error.mjs.map +1 -1
  605. package/dist/utils/index.mjs +2 -2
  606. package/package.json +32 -26
  607. package/dist/adapters/http/middleware/built-in/assets.d.ts +0 -11
  608. package/dist/adapters/http/middleware/built-in/assets.d.ts.map +0 -1
  609. package/dist/adapters/http/middleware/built-in/assets.mjs +0 -91
  610. package/dist/adapters/http/middleware/built-in/assets.mjs.map +0 -1
  611. package/dist/adapters/http/middleware/built-in/theme.d.ts +0 -15
  612. package/dist/adapters/http/middleware/built-in/theme.d.ts.map +0 -1
  613. package/dist/adapters/http/middleware/built-in/theme.mjs +0 -27
  614. package/dist/adapters/http/middleware/built-in/theme.mjs.map +0 -1
  615. package/dist/adapters/http/middleware/built-in/types.d.ts +0 -14
  616. package/dist/adapters/http/middleware/built-in/types.d.ts.map +0 -1
  617. package/dist/adapters/http/middleware/built-in/ui-http-client.d.ts +0 -15
  618. package/dist/adapters/http/middleware/built-in/ui-http-client.d.ts.map +0 -1
  619. package/dist/adapters/http/middleware/built-in/ui-http-client.mjs +0 -25
  620. package/dist/adapters/http/middleware/built-in/ui-http-client.mjs.map +0 -1
  621. package/dist/adapters/http/request/helpers/redirect.d.ts +0 -14
  622. package/dist/adapters/http/request/helpers/redirect.d.ts.map +0 -1
  623. package/dist/adapters/http/request/helpers/redirect.mjs +0 -36
  624. package/dist/adapters/http/request/helpers/redirect.mjs.map +0 -1
  625. package/dist/adapters/http/ui/account-console/index.d.ts +0 -4
  626. package/dist/adapters/http/ui/account-console/index.d.ts.map +0 -1
  627. package/dist/adapters/http/ui/account-console/index.mjs +0 -6
  628. package/dist/adapters/http/ui/account-console/module.d.ts +0 -28
  629. package/dist/adapters/http/ui/account-console/module.d.ts.map +0 -1
  630. package/dist/adapters/http/ui/account-console/module.mjs +0 -80
  631. package/dist/adapters/http/ui/account-console/module.mjs.map +0 -1
  632. package/dist/adapters/http/ui/account-console/ref.d.ts +0 -30
  633. package/dist/adapters/http/ui/account-console/ref.d.ts.map +0 -1
  634. package/dist/adapters/http/ui/account-console/ref.mjs +0 -50
  635. package/dist/adapters/http/ui/account-console/ref.mjs.map +0 -1
  636. package/dist/adapters/http/ui/account-console/types.d.ts +0 -11
  637. package/dist/adapters/http/ui/account-console/types.d.ts.map +0 -1
  638. package/dist/adapters/http/ui/auth-console/http-client.d.ts +0 -22
  639. package/dist/adapters/http/ui/auth-console/http-client.d.ts.map +0 -1
  640. package/dist/adapters/http/ui/auth-console/http-client.mjs.map +0 -1
  641. package/dist/adapters/http/ui/auth-console/index.d.ts +0 -6
  642. package/dist/adapters/http/ui/auth-console/index.d.ts.map +0 -1
  643. package/dist/adapters/http/ui/auth-console/index.mjs +0 -8
  644. package/dist/adapters/http/ui/auth-console/module.d.ts +0 -4
  645. package/dist/adapters/http/ui/auth-console/module.d.ts.map +0 -1
  646. package/dist/adapters/http/ui/auth-console/module.mjs +0 -73
  647. package/dist/adapters/http/ui/auth-console/module.mjs.map +0 -1
  648. package/dist/adapters/http/ui/auth-console/resolve.d.ts +0 -21
  649. package/dist/adapters/http/ui/auth-console/resolve.d.ts.map +0 -1
  650. package/dist/adapters/http/ui/auth-console/resolve.mjs +0 -53
  651. package/dist/adapters/http/ui/auth-console/resolve.mjs.map +0 -1
  652. package/dist/adapters/http/ui/auth-console/serve.d.ts +0 -9
  653. package/dist/adapters/http/ui/auth-console/serve.d.ts.map +0 -1
  654. package/dist/adapters/http/ui/auth-console/serve.mjs +0 -35
  655. package/dist/adapters/http/ui/auth-console/serve.mjs.map +0 -1
  656. package/dist/adapters/http/ui/auth-console/types.d.ts +0 -26
  657. package/dist/adapters/http/ui/auth-console/types.d.ts.map +0 -1
  658. package/dist/adapters/http/ui/console-packages/index.d.ts.map +0 -1
  659. package/dist/adapters/http/ui/console-packages/index.mjs +0 -5
  660. package/dist/adapters/http/ui/console-packages/module.d.ts +0 -33
  661. package/dist/adapters/http/ui/console-packages/module.d.ts.map +0 -1
  662. package/dist/adapters/http/ui/console-packages/module.mjs +0 -70
  663. package/dist/adapters/http/ui/console-packages/module.mjs.map +0 -1
  664. package/dist/adapters/http/ui/console-packages/types.d.ts +0 -12
  665. package/dist/adapters/http/ui/console-packages/types.d.ts.map +0 -1
  666. package/dist/adapters/http/ui/index.d.ts +0 -6
  667. package/dist/adapters/http/ui/index.d.ts.map +0 -1
  668. package/dist/adapters/http/ui/index.mjs +0 -25
  669. package/dist/adapters/http/ui/shared/html.d.ts +0 -76
  670. package/dist/adapters/http/ui/shared/html.d.ts.map +0 -1
  671. package/dist/adapters/http/ui/shared/html.mjs +0 -104
  672. package/dist/adapters/http/ui/shared/html.mjs.map +0 -1
  673. package/dist/adapters/http/ui/shared/index.d.ts +0 -2
  674. package/dist/adapters/http/ui/shared/index.d.ts.map +0 -1
  675. package/dist/adapters/http/ui/shared/index.mjs +0 -5
  676. package/dist/adapters/http/ui/theme/apply.d.ts +0 -12
  677. package/dist/adapters/http/ui/theme/apply.d.ts.map +0 -1
  678. package/dist/adapters/http/ui/theme/apply.mjs +0 -29
  679. package/dist/adapters/http/ui/theme/apply.mjs.map +0 -1
  680. package/dist/adapters/http/ui/theme/assets.d.ts +0 -20
  681. package/dist/adapters/http/ui/theme/assets.d.ts.map +0 -1
  682. package/dist/adapters/http/ui/theme/assets.mjs +0 -86
  683. package/dist/adapters/http/ui/theme/assets.mjs.map +0 -1
  684. package/dist/adapters/http/ui/theme/constants.d.ts +0 -16
  685. package/dist/adapters/http/ui/theme/constants.d.ts.map +0 -1
  686. package/dist/adapters/http/ui/theme/constants.mjs +0 -20
  687. package/dist/adapters/http/ui/theme/constants.mjs.map +0 -1
  688. package/dist/adapters/http/ui/theme/contract/constants.d.ts +0 -120
  689. package/dist/adapters/http/ui/theme/contract/constants.d.ts.map +0 -1
  690. package/dist/adapters/http/ui/theme/contract/constants.mjs +0 -136
  691. package/dist/adapters/http/ui/theme/contract/constants.mjs.map +0 -1
  692. package/dist/adapters/http/ui/theme/contract/head.d.ts +0 -12
  693. package/dist/adapters/http/ui/theme/contract/head.d.ts.map +0 -1
  694. package/dist/adapters/http/ui/theme/contract/head.mjs +0 -61
  695. package/dist/adapters/http/ui/theme/contract/head.mjs.map +0 -1
  696. package/dist/adapters/http/ui/theme/contract/index.d.ts +0 -6
  697. package/dist/adapters/http/ui/theme/contract/index.d.ts.map +0 -1
  698. package/dist/adapters/http/ui/theme/contract/index.mjs +0 -8
  699. package/dist/adapters/http/ui/theme/contract/manifest.d.ts +0 -25
  700. package/dist/adapters/http/ui/theme/contract/manifest.d.ts.map +0 -1
  701. package/dist/adapters/http/ui/theme/contract/manifest.mjs +0 -77
  702. package/dist/adapters/http/ui/theme/contract/manifest.mjs.map +0 -1
  703. package/dist/adapters/http/ui/theme/contract/types.d.ts +0 -26
  704. package/dist/adapters/http/ui/theme/contract/types.d.ts.map +0 -1
  705. package/dist/adapters/http/ui/theme/contract/utils.d.ts +0 -11
  706. package/dist/adapters/http/ui/theme/contract/utils.d.ts.map +0 -1
  707. package/dist/adapters/http/ui/theme/contract/utils.mjs +0 -22
  708. package/dist/adapters/http/ui/theme/contract/utils.mjs.map +0 -1
  709. package/dist/adapters/http/ui/theme/index.d.ts +0 -7
  710. package/dist/adapters/http/ui/theme/index.d.ts.map +0 -1
  711. package/dist/adapters/http/ui/theme/index.mjs +0 -13
  712. package/dist/adapters/http/ui/theme/module.d.ts +0 -79
  713. package/dist/adapters/http/ui/theme/module.d.ts.map +0 -1
  714. package/dist/adapters/http/ui/theme/module.mjs +0 -206
  715. package/dist/adapters/http/ui/theme/module.mjs.map +0 -1
  716. package/dist/adapters/http/ui/theme/types.d.ts +0 -42
  717. package/dist/adapters/http/ui/theme/types.d.ts.map +0 -1
  718. package/dist/app/modules/config/helpers.d.ts +0 -9
  719. package/dist/app/modules/config/helpers.d.ts.map +0 -1
  720. package/dist/app/modules/config/helpers.mjs +0 -22
  721. package/dist/app/modules/config/helpers.mjs.map +0 -1
  722. package/dist/app/modules/config/normalize.d.ts +0 -3
  723. package/dist/app/modules/config/normalize.d.ts.map +0 -1
  724. package/dist/app/modules/config/normalize.mjs +0 -117
  725. package/dist/app/modules/config/normalize.mjs.map +0 -1
  726. package/dist/app/modules/config/origins.d.ts +0 -25
  727. package/dist/app/modules/config/origins.d.ts.map +0 -1
  728. package/dist/app/modules/config/origins.mjs +0 -46
  729. package/dist/app/modules/config/origins.mjs.map +0 -1
  730. package/dist/app/modules/config/read/env.d.ts +0 -3
  731. package/dist/app/modules/config/read/env.d.ts.map +0 -1
  732. package/dist/app/modules/config/read/env.mjs +0 -139
  733. package/dist/app/modules/config/read/env.mjs.map +0 -1
  734. package/dist/app/modules/config/read/fs.d.ts +0 -3
  735. package/dist/app/modules/config/read/fs.d.ts.map +0 -1
  736. package/dist/app/modules/config/read/fs.mjs +0 -60
  737. package/dist/app/modules/config/read/fs.mjs.map +0 -1
  738. package/dist/app/modules/config/read/index.d.ts +0 -5
  739. package/dist/app/modules/config/read/index.d.ts.map +0 -1
  740. package/dist/app/modules/config/read/index.mjs +0 -7
  741. package/dist/app/modules/config/read/module.d.ts +0 -4
  742. package/dist/app/modules/config/read/module.d.ts.map +0 -1
  743. package/dist/app/modules/config/read/module.mjs +0 -29
  744. package/dist/app/modules/config/read/module.mjs.map +0 -1
  745. package/dist/app/modules/config/read/types.d.ts +0 -9
  746. package/dist/app/modules/config/read/types.d.ts.map +0 -1
  747. package/dist/app/modules/config/trust-proxy.d.ts +0 -28
  748. package/dist/app/modules/config/trust-proxy.d.ts.map +0 -1
  749. package/dist/app/modules/config/trust-proxy.mjs +0 -64
  750. package/dist/app/modules/config/trust-proxy.mjs.map +0 -1
  751. package/dist/cli/config.d.ts +0 -18
  752. package/dist/cli/config.d.ts.map +0 -1
  753. package/dist/cli/config.mjs +0 -34
  754. package/dist/cli/config.mjs.map +0 -1
  755. package/dist/cli/types.d.ts.map +0 -1
  756. package/dist/utils/host.d.ts +0 -2
  757. package/dist/utils/host.d.ts.map +0 -1
  758. package/dist/utils/host.mjs +0 -12
  759. package/dist/utils/host.mjs.map +0 -1
  760. /package/dist/adapters/http/{middleware/built-in → controllers/workflows/account}/types.mjs +0 -0
  761. /package/dist/adapters/http/{ui/console-packages → controllers/workflows/admin}/index.d.ts +0 -0
  762. /package/dist/adapters/http/{ui/account-console → controllers/workflows/admin}/types.mjs +0 -0
  763. /package/dist/adapters/http/{ui/auth-console → controllers/workflows/console-login}/types.mjs +0 -0
  764. /package/dist/adapters/http/{ui/console-packages → internal-client}/types.mjs +0 -0
  765. /package/dist/{adapters/http/ui/theme/contract → app/modules/components}/types.mjs +0 -0
  766. /package/dist/cli/{types.d.ts → commands/types.d.ts} +0 -0
  767. /package/dist/{adapters/http/ui/theme → cli/commands}/types.mjs +0 -0
  768. /package/dist/{app/modules/config/read → core/oauth2/backchannel-logout}/types.mjs +0 -0
  769. /package/dist/{cli → core/oauth2/console-login}/types.mjs +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","createRelationsReadGate","schemaMapping","realm","REALM","userSchema","name","USER","indexes","fields","default","allowed","filters","indexed","relations","validate","sorts","pagination","maxLimit"],"sources":["../../../../src/core/entities/user/schema.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { defineSchema } from '@rapiq/core';\nimport type { User } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\nimport { createRelationsReadGate } from '../../query/relations.ts';\n\nconst schemaMapping = { realm: EntityType.REALM };\n\nexport const userSchema = defineSchema<User>({\n name: EntityType.USER,\n indexes: [\n ['id'],\n ['name', 'realmId'],\n ['displayName'],\n ['realmId'],\n ['active'],\n ['createdAt'],\n ['updatedAt'],\n ],\n fields: {\n default: [\n 'id',\n 'name',\n 'nameLocked',\n 'firstName',\n 'lastName',\n 'displayName',\n 'avatar',\n 'cover',\n 'active',\n 'status',\n 'statusMessage',\n 'createdAt',\n 'updatedAt',\n 'realmId',\n ],\n allowed: ['email'],\n },\n filters: { allowed: ['id', 'name', 'displayName', 'realmId', 'active'], indexed: true },\n relations: { allowed: ['realm'], validate: createRelationsReadGate(schemaMapping) },\n sorts: { allowed: ['id', 'name', 'displayName', 'createdAt', 'updatedAt'], indexed: true },\n pagination: { maxLimit: 50 },\n schemaMapping,\n});\n"],"mappings":";;;;;;;AAYA,MAAMG,gBAAgB,EAAEC,OAAOH,WAAWI,MAAM;AAEhD,MAAaC,aAAaN,aAAmB;CACzCO,MAAMN,WAAWO;CACjBC,SAAS;EACL,CAAC,IAAK;EACN,CAAC,QAAQ,SAAU;EACnB,CAAC,aAAc;EACf,CAAC,SAAU;EACX,CAAC,QAAS;EACV,CAAC,WAAY;EACb,CAAC,WAAY;CAChB;CACDC,QAAQ;EACJC,SAAS;GACL;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACH;EACDC,SAAS,CAAC,OAAQ;CACtB;CACAC,SAAS;EAAED,SAAS;GAAC;GAAM;GAAQ;GAAe;GAAW;EAAS;EAAEE,SAAS;CAAK;CACtFC,WAAW;EAAEH,SAAS,CAAC,OAAQ;EAAEI,UAAUd,wBAAwBC,aAAAA;CAAe;CAClFc,OAAO;EAAEL,SAAS;GAAC;GAAM;GAAQ;GAAe;GAAa;EAAY;EAAEE,SAAS;CAAK;CACzFI,YAAY,EAAEC,UAAU,GAAG;CAC3BhB;AACJ,CAAA"}
1
+ {"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","createRelationsReadGate","schemaMapping","realm","REALM","userSchema","name","USER","indexes","fields","default","allowed","filters","indexed","relations","validate","sorts","pagination","maxLimit"],"sources":["../../../../src/core/entities/user/schema.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { defineSchema } from '@rapiq/core';\nimport type { User } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\nimport { createRelationsReadGate } from '../../query/relations.ts';\n\nconst schemaMapping = { realm: EntityType.REALM };\n\nexport const userSchema = defineSchema<User>({\n name: EntityType.USER,\n indexes: [\n ['id'],\n ['name', 'realmId'],\n ['displayName'],\n ['realmId'],\n ['active'],\n ['createdAt'],\n ['updatedAt'],\n ],\n fields: {\n default: [\n 'id',\n 'name',\n 'nameLocked',\n 'firstName',\n 'lastName',\n 'displayName',\n 'emailVerified',\n 'avatar',\n 'cover',\n 'active',\n 'status',\n 'statusMessage',\n 'createdAt',\n 'updatedAt',\n 'realmId',\n ],\n allowed: ['email'],\n },\n filters: { allowed: ['id', 'name', 'displayName', 'realmId', 'active'], indexed: true },\n relations: { allowed: ['realm'], validate: createRelationsReadGate(schemaMapping) },\n sorts: { allowed: ['id', 'name', 'displayName', 'createdAt', 'updatedAt'], indexed: true },\n pagination: { maxLimit: 50 },\n schemaMapping,\n});\n"],"mappings":";;;;;;;AAYA,MAAMG,gBAAgB,EAAEC,OAAOH,WAAWI,MAAM;AAEhD,MAAaC,aAAaN,aAAmB;CACzCO,MAAMN,WAAWO;CACjBC,SAAS;EACL,CAAC,IAAK;EACN,CAAC,QAAQ,SAAU;EACnB,CAAC,aAAc;EACf,CAAC,SAAU;EACX,CAAC,QAAS;EACV,CAAC,WAAY;EACb,CAAC,WAAY;CAChB;CACDC,QAAQ;EACJC,SAAS;GACL;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACH;EACDC,SAAS,CAAC,OAAQ;CACtB;CACAC,SAAS;EAAED,SAAS;GAAC;GAAM;GAAQ;GAAe;GAAW;EAAS;EAAEE,SAAS;CAAK;CACtFC,WAAW;EAAEH,SAAS,CAAC,OAAQ;EAAEI,UAAUd,wBAAwBC,aAAAA;CAAe;CAClFc,OAAO;EAAEL,SAAS;GAAC;GAAM;GAAQ;GAAe;GAAa;EAAY;EAAEE,SAAS;CAAK;CACzFI,YAAY,EAAEC,UAAU,GAAG;CAC3BhB;AACJ,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/user/service.ts"],"names":[],"mappings":"AAWA,OAAO,EAEH,aAAa,EAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAG,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAIhE,MAAM,MAAM,kBAAkB,GAAG;IAC7B,UAAU,EAAE,eAAe,CAAC;IAC5B,eAAe,EAAE,gBAAgB,CAAC;IAClC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,qBAAa,WAAY,SAAQ,qBAAsB,YAAW,YAAY;IAC1E,SAAS,CAAC,UAAU,EAAE,eAAe,CAAC;IAEtC,SAAS,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAE5C,SAAS,CAAC,SAAS,EAAE,aAAa,CAAC;gBAEvB,GAAG,EAAE,kBAAkB;IAO7B,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;IA8E1C,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,OAAO,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IA8CV,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAKV,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAKV,IAAI,CACN,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAO,GACvC,OAAO,CAAC;QACP,MAAM,EAAE,IAAI,CAAC;QACb,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC;IAwII,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;CA2BnB"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/user/service.ts"],"names":[],"mappings":"AAWA,OAAO,EAEH,aAAa,EAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAG,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAIhE,MAAM,MAAM,kBAAkB,GAAG;IAC7B,UAAU,EAAE,eAAe,CAAC;IAC5B,eAAe,EAAE,gBAAgB,CAAC;IAClC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,qBAAa,WAAY,SAAQ,qBAAsB,YAAW,YAAY;IAC1E,SAAS,CAAC,UAAU,EAAE,eAAe,CAAC;IAEtC,SAAS,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAE5C,SAAS,CAAC,SAAS,EAAE,aAAa,CAAC;gBAEvB,GAAG,EAAE,kBAAkB;IAO7B,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;IA8E1C,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,OAAO,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IA8CV,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAKV,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAKV,IAAI,CACN,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAO,GACvC,OAAO,CAAC;QACP,MAAM,EAAE,IAAI,CAAC;QACb,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC;IAuNI,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;CA2BnB"}
@@ -141,6 +141,11 @@ var UserService = class extends AbstractEntityService {
141
141
  if (entity) {
142
142
  const originalName = entity.name;
143
143
  const originalNameLocked = entity.nameLocked;
144
+ let emailChanged = false;
145
+ if (validated.email && (typeof validated.emailVerified === "undefined" || validated.emailVerified === entity.emailVerified)) {
146
+ const current = await this.repository.findOneByWithEmail({ id: entity.id });
147
+ emailChanged = !!current && current.email !== validated.email;
148
+ }
144
149
  if (isSelfEdit) await actor.permissionEvaluator.evaluate({
145
150
  name: PermissionName.USER_SELF_MANAGE,
146
151
  data: definePolicyData({
@@ -148,6 +153,7 @@ var UserService = class extends AbstractEntityService {
148
153
  ...this.resourceRealmMatch(validated)
149
154
  })
150
155
  });
156
+ const before = { ...entity };
151
157
  entity = this.repository.merge(entity, validated);
152
158
  if (validated.name && validated.name !== originalName) {
153
159
  if (validated.nameLocked) entity.nameLocked = validated.nameLocked;
@@ -163,8 +169,22 @@ var UserService = class extends AbstractEntityService {
163
169
  [BuiltInPolicyType.REALM_MATCH]: validated.realmId ?? entity.realmId ?? null
164
170
  })
165
171
  });
172
+ if (emailChanged) entity.emailVerified = false;
166
173
  if (validated.password) entity.password = await credentialsService.protect(validated.password);
167
- await this.repository.save(entity);
174
+ const patch = { ...validated };
175
+ for (const key of Object.keys(patch)) if (patch[key] === before[key]) delete patch[key];
176
+ if (entity.name === originalName) delete patch.name;
177
+ if (emailChanged) patch.emailVerified = false;
178
+ if (validated.password) patch.password = entity.password;
179
+ const { id } = entity;
180
+ entity = await this.repository.transaction(async (repository) => {
181
+ const current = await repository.findOneBy({ id });
182
+ if (!current) throw new EntityNotFoundError();
183
+ const { name: currentName, nameLocked: currentNameLocked } = current;
184
+ const merged = repository.merge(current, patch);
185
+ if (currentNameLocked && patch.name && validated.nameLocked !== false) merged.name = currentName;
186
+ return repository.save(merged);
187
+ });
168
188
  return {
169
189
  entity,
170
190
  created: false
@@ -1 +1 @@
1
- {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","definePolicyData","ValidatorGroup","isUUID","EntityNotFoundError","ValidationError","eq","inArray","or","PermissionName","UserValidator","AbstractEntityService","UserCredentialsService","appendQueryConditions","decodeQuery","userSchema","UserService","repository","realmRepository","validator","ctx","passwordMinLength","getMany","query","actor","permissionNames","USER_READ","USER_UPDATE","USER_DELETE","permissionEvaluator","preEvaluateOneOf","name","parsed","schema","compiled","compile","verdict","self","identity","type","data","id","scoped","condition","findMany","entities","meta","total","entity","push","evaluateOneOf","ATTRIBUTES","resourceRealmMatch","getOne","idOrName","realmId","isMe","findOne","parameters","create","save","undefined","update","updateOnly","options","group","realm","resolve","where","findOneBy","isSelfEdit","preEvaluate","e","USER_SELF_MANAGE","UPDATE","USER_CREATE","CREATE","validated","run","validateJoinColumns","credentialsService","originalName","originalNameLocked","nameLocked","evaluate","merge","REALM_MATCH","password","protect","created","actorRealmId","getActorRealmId","delete","entityId","remove"],"sources":["../../../../src/core/entities/user/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BuiltInPolicyType, definePolicyData } from '@authup/access';\nimport { ValidatorGroup, isUUID } from '@authup/kit';\nimport { EntityNotFoundError, ValidationError } from '@authup/errors';\nimport { eq, inArray, or } from '@rapiq/core';\nimport {\n PermissionName,\n UserValidator,\n} from '@authup/core-kit';\nimport type { User } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type { IRealmRepository } from '../realm/types.ts';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport { UserCredentialsService } from '../../authentication/credential/entities/user/module.ts';\nimport type { IUserRepository, IUserService } from './types.ts';\nimport { appendQueryConditions, decodeQuery } from '../../query/index.ts';\nimport { userSchema } from './schema.ts';\n\nexport type UserServiceContext = {\n repository: IUserRepository;\n realmRepository: IRealmRepository;\n passwordMinLength?: number;\n};\n\nexport class UserService extends AbstractEntityService implements IUserService {\n protected repository: IUserRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected validator: UserValidator;\n\n constructor(ctx: UserServiceContext) {\n super();\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.validator = new UserValidator({ passwordMinLength: ctx.passwordMinLength });\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<User>> {\n const permissionNames = [\n PermissionName.USER_READ,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n ];\n\n await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });\n\n const parsed = await decodeQuery(query, { schema: userSchema, actor });\n\n // Compile the read permissions into a row condition (#3286 phase 3). The\n // own row is always readable, so the self short-circuit composes as an\n // OR-alternative — the whole gate runs as WHERE and pagination/totals\n // stay exact. A non-expressible policy falls back to the per-row loop\n // below.\n const compiled = await actor.permissionEvaluator.compile({ name: permissionNames });\n if (compiled.verdict !== 'post') {\n const self = actor.identity && actor.identity.type === 'user' ?\n eq('id', actor.identity.data.id) :\n null;\n\n let scoped = parsed;\n if (compiled.verdict === 'deny') {\n scoped = appendQueryConditions(parsed, self ?? inArray('id', []));\n } else if (compiled.verdict === 'conditional') {\n scoped = appendQueryConditions(\n parsed,\n self ? or(self, compiled.condition) : compiled.condition,\n );\n }\n\n return this.repository.findMany(scoped);\n }\n\n const {\n data: entities,\n meta,\n } = await this.repository.findMany(parsed);\n\n const data: User[] = [];\n let { total } = meta;\n\n for (const entity of entities) {\n if (\n actor.identity &&\n actor.identity.type === 'user' &&\n actor.identity.data.id === entity.id\n ) {\n data.push(entity);\n continue;\n }\n\n try {\n await actor.permissionEvaluator.evaluateOneOf({\n name: [\n PermissionName.USER_READ,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n ],\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity, ...this.resourceRealmMatch(entity) }),\n });\n\n data.push(entity);\n } catch {\n total -= 1;\n }\n }\n\n return {\n data,\n meta: {\n ...meta,\n total, \n }, \n };\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n query?: Record<string, any>,\n realmId?: string,\n ): Promise<User> {\n const permissionNames = [\n PermissionName.USER_READ,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n ];\n\n let isMe = !!actor.identity &&\n actor.identity.type === 'user' &&\n (\n actor.identity.data.id === idOrName ||\n actor.identity.data.name === idOrName\n );\n\n if (!isMe) {\n await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });\n }\n\n const entity = await this.repository.findOne(\n idOrName,\n await decodeQuery(query, {\n schema: userSchema, \n parameters: ['fields', 'relations'], \n actor, \n }),\n realmId,\n );\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n if (isMe && actor.identity!.data.id !== entity.id) {\n isMe = false;\n await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });\n }\n\n if (!isMe) {\n await actor.permissionEvaluator.evaluateOneOf({\n name: permissionNames,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity, ...this.resourceRealmMatch(entity) }),\n });\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<User> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<User> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: User,\n created: boolean \n }> {\n let group: string;\n\n const realm = typeof data.realmId === 'string' ?\n await this.realmRepository.resolve(data.realmId) :\n undefined;\n\n let entity: User | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n if (realm) {\n where.realmId = realm.id;\n }\n\n entity = await this.repository.findOneBy(where);\n // Only a NAME key may upsert-create. A UUID addresses one specific\n // row, so a miss is a 404 (creating would write a different id).\n if (!entity && (options.updateOnly || where.id)) {\n throw new EntityNotFoundError();\n }\n } else if (options.updateOnly) {\n throw new EntityNotFoundError();\n }\n\n let isSelfEdit = false;\n if (entity) {\n try {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_UPDATE });\n } catch (e) {\n if (\n !actor.identity ||\n actor.identity.type !== 'user' ||\n actor.identity.data.id !== entity.id\n ) {\n throw e;\n }\n isSelfEdit = true;\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_SELF_MANAGE });\n }\n\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_CREATE });\n\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validator.run(data, { group });\n\n await this.repository.validateJoinColumns(validated);\n\n const credentialsService = new UserCredentialsService();\n\n if (entity) {\n const originalName = entity.name;\n const originalNameLocked = entity.nameLocked;\n\n if (isSelfEdit) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_SELF_MANAGE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated, ...this.resourceRealmMatch(validated) }),\n });\n }\n\n entity = this.repository.merge(entity, validated);\n\n if (\n validated.name &&\n validated.name !== originalName\n ) {\n if (validated.nameLocked) {\n entity.nameLocked = validated.nameLocked;\n }\n\n if (originalNameLocked && validated.nameLocked !== false) {\n entity.name = originalName;\n }\n }\n\n if (!isSelfEdit) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n [BuiltInPolicyType.REALM_MATCH]: validated.realmId ?? entity.realmId ?? null,\n }),\n });\n }\n\n if (validated.password) {\n entity.password = await credentialsService.protect(validated.password);\n }\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: false, \n };\n }\n\n if (!validated.realmId) {\n const actorRealmId = this.getActorRealmId(actor);\n if (actorRealmId) {\n validated.realmId = actorRealmId;\n }\n }\n\n entity = this.repository.create(validated);\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_CREATE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity, ...this.resourceRealmMatch(entity) }),\n });\n\n if (validated.password) {\n entity.password = await credentialsService.protect(validated.password);\n }\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: true, \n };\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<User> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_DELETE });\n\n if (\n actor.identity &&\n actor.identity.type === 'user' &&\n actor.identity.data.id === id\n ) {\n throw new ValidationError('The own user can not be deleted.');\n }\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_DELETE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity, ...this.resourceRealmMatch(entity) }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","definePolicyData","ValidatorGroup","isUUID","EntityNotFoundError","ValidationError","eq","inArray","or","PermissionName","UserValidator","AbstractEntityService","UserCredentialsService","appendQueryConditions","decodeQuery","userSchema","UserService","repository","realmRepository","validator","ctx","passwordMinLength","getMany","query","actor","permissionNames","USER_READ","USER_UPDATE","USER_DELETE","permissionEvaluator","preEvaluateOneOf","name","parsed","schema","compiled","compile","verdict","self","identity","type","data","id","scoped","condition","findMany","entities","meta","total","entity","push","evaluateOneOf","ATTRIBUTES","resourceRealmMatch","getOne","idOrName","realmId","isMe","findOne","parameters","create","save","undefined","update","updateOnly","options","group","realm","resolve","where","findOneBy","isSelfEdit","preEvaluate","e","USER_SELF_MANAGE","UPDATE","USER_CREATE","CREATE","validated","run","validateJoinColumns","credentialsService","originalName","originalNameLocked","nameLocked","emailChanged","email","emailVerified","current","findOneByWithEmail","evaluate","before","merge","REALM_MATCH","password","protect","patch","key","Object","keys","transaction","currentName","currentNameLocked","merged","created","actorRealmId","getActorRealmId","delete","entityId","remove"],"sources":["../../../../src/core/entities/user/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BuiltInPolicyType, definePolicyData } from '@authup/access';\nimport { ValidatorGroup, isUUID } from '@authup/kit';\nimport { EntityNotFoundError, ValidationError } from '@authup/errors';\nimport { eq, inArray, or } from '@rapiq/core';\nimport {\n PermissionName,\n UserValidator,\n} from '@authup/core-kit';\nimport type { User } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type { IRealmRepository } from '../realm/types.ts';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport { UserCredentialsService } from '../../authentication/credential/entities/user/module.ts';\nimport type { IUserRepository, IUserService } from './types.ts';\nimport { appendQueryConditions, decodeQuery } from '../../query/index.ts';\nimport { userSchema } from './schema.ts';\n\nexport type UserServiceContext = {\n repository: IUserRepository;\n realmRepository: IRealmRepository;\n passwordMinLength?: number;\n};\n\nexport class UserService extends AbstractEntityService implements IUserService {\n protected repository: IUserRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected validator: UserValidator;\n\n constructor(ctx: UserServiceContext) {\n super();\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.validator = new UserValidator({ passwordMinLength: ctx.passwordMinLength });\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<User>> {\n const permissionNames = [\n PermissionName.USER_READ,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n ];\n\n await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });\n\n const parsed = await decodeQuery(query, { schema: userSchema, actor });\n\n // Compile the read permissions into a row condition (#3286 phase 3). The\n // own row is always readable, so the self short-circuit composes as an\n // OR-alternative — the whole gate runs as WHERE and pagination/totals\n // stay exact. A non-expressible policy falls back to the per-row loop\n // below.\n const compiled = await actor.permissionEvaluator.compile({ name: permissionNames });\n if (compiled.verdict !== 'post') {\n const self = actor.identity && actor.identity.type === 'user' ?\n eq('id', actor.identity.data.id) :\n null;\n\n let scoped = parsed;\n if (compiled.verdict === 'deny') {\n scoped = appendQueryConditions(parsed, self ?? inArray('id', []));\n } else if (compiled.verdict === 'conditional') {\n scoped = appendQueryConditions(\n parsed,\n self ? or(self, compiled.condition) : compiled.condition,\n );\n }\n\n return this.repository.findMany(scoped);\n }\n\n const {\n data: entities,\n meta,\n } = await this.repository.findMany(parsed);\n\n const data: User[] = [];\n let { total } = meta;\n\n for (const entity of entities) {\n if (\n actor.identity &&\n actor.identity.type === 'user' &&\n actor.identity.data.id === entity.id\n ) {\n data.push(entity);\n continue;\n }\n\n try {\n await actor.permissionEvaluator.evaluateOneOf({\n name: [\n PermissionName.USER_READ,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n ],\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity, ...this.resourceRealmMatch(entity) }),\n });\n\n data.push(entity);\n } catch {\n total -= 1;\n }\n }\n\n return {\n data,\n meta: {\n ...meta,\n total, \n }, \n };\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n query?: Record<string, any>,\n realmId?: string,\n ): Promise<User> {\n const permissionNames = [\n PermissionName.USER_READ,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n ];\n\n let isMe = !!actor.identity &&\n actor.identity.type === 'user' &&\n (\n actor.identity.data.id === idOrName ||\n actor.identity.data.name === idOrName\n );\n\n if (!isMe) {\n await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });\n }\n\n const entity = await this.repository.findOne(\n idOrName,\n await decodeQuery(query, {\n schema: userSchema, \n parameters: ['fields', 'relations'], \n actor, \n }),\n realmId,\n );\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n if (isMe && actor.identity!.data.id !== entity.id) {\n isMe = false;\n await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });\n }\n\n if (!isMe) {\n await actor.permissionEvaluator.evaluateOneOf({\n name: permissionNames,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity, ...this.resourceRealmMatch(entity) }),\n });\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<User> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<User> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: User,\n created: boolean \n }> {\n let group: string;\n\n const realm = typeof data.realmId === 'string' ?\n await this.realmRepository.resolve(data.realmId) :\n undefined;\n\n let entity: User | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n if (realm) {\n where.realmId = realm.id;\n }\n\n entity = await this.repository.findOneBy(where);\n // Only a NAME key may upsert-create. A UUID addresses one specific\n // row, so a miss is a 404 (creating would write a different id).\n if (!entity && (options.updateOnly || where.id)) {\n throw new EntityNotFoundError();\n }\n } else if (options.updateOnly) {\n throw new EntityNotFoundError();\n }\n\n let isSelfEdit = false;\n if (entity) {\n try {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_UPDATE });\n } catch (e) {\n if (\n !actor.identity ||\n actor.identity.type !== 'user' ||\n actor.identity.data.id !== entity.id\n ) {\n throw e;\n }\n isSelfEdit = true;\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_SELF_MANAGE });\n }\n\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_CREATE });\n\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validator.run(data, { group });\n\n await this.repository.validateJoinColumns(validated);\n\n const credentialsService = new UserCredentialsService();\n\n if (entity) {\n const originalName = entity.name;\n const originalNameLocked = entity.nameLocked;\n\n // A changed address carries none of the old one's verification, and\n // `email` is NOT on the self-manage denylist, so without this a user\n // verifies their own address and then edits it to someone else's\n // while the claim keeps asserting `email_verified: true`: the very\n // account-linking takeover the claim is read for (#3519).\n //\n // The old value has to be re-read: the entity loaded above carries\n // no `email` at all, because the column is `select: false`. Read\n // BEFORE the merge below, which writes the new address onto that\n // same entity.\n //\n // An `emailVerified` that DIFFERS from the stored value is a\n // deliberate assertion and wins, so an admin can change the address\n // and vouch for the new one in one request. One merely ECHOED back\n // is not: `AUserForm` posts its whole reactive state on every save,\n // hydrated from the record it loaded, so treating presence alone as\n // an assertion made the rule unreachable from the console: every\n // address change there carried the stale `true` straight through.\n let emailChanged = false;\n if (\n validated.email &&\n (\n typeof validated.emailVerified === 'undefined' ||\n validated.emailVerified === entity.emailVerified\n )\n ) {\n const current = await this.repository.findOneByWithEmail({ id: entity.id });\n emailChanged = !!current && current.email !== validated.email;\n }\n\n if (isSelfEdit) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_SELF_MANAGE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated, ...this.resourceRealmMatch(validated) }),\n });\n }\n\n const before: Partial<User> = { ...entity };\n entity = this.repository.merge(entity, validated);\n\n if (\n validated.name &&\n validated.name !== originalName\n ) {\n if (validated.nameLocked) {\n entity.nameLocked = validated.nameLocked;\n }\n\n if (originalNameLocked && validated.nameLocked !== false) {\n entity.name = originalName;\n }\n }\n\n if (!isSelfEdit) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n [BuiltInPolicyType.REALM_MATCH]: validated.realmId ?? entity.realmId ?? null,\n }),\n });\n }\n\n if (emailChanged) {\n entity.emailVerified = false;\n }\n\n if (validated.password) {\n entity.password = await credentialsService.protect(validated.password);\n }\n\n // Only the write runs inside the transaction. It pins one pooled\n // connection, and the permission evaluator, the join-column check\n // and the email re-read above each take their own from the same\n // pool, so wrapping them too deadlocks the DataSource under ten\n // concurrent saves. The fresh row is lock-read and this request's\n // patch merged onto it: TypeORM writes only the columns that\n // differ, so a concurrent writer's columns survive (#3526).\n const patch: Partial<User> = { ...validated };\n // A field echoed back with the value this request read is no\n // intent to change it (the console posts its whole form), and\n // writing it would overwrite a concurrent change. The name-lock\n // revert falls under the same rule: a stale originalName must not\n // overwrite a concurrent rename.\n for (const key of Object.keys(patch) as (keyof User)[]) {\n if (patch[key] === before[key]) {\n delete patch[key];\n }\n }\n if (entity.name === originalName) {\n delete patch.name;\n }\n if (emailChanged) {\n patch.emailVerified = false;\n }\n if (validated.password) {\n patch.password = entity.password;\n }\n\n const { id } = entity;\n entity = await this.repository.transaction(async (repository) => {\n const current = await repository.findOneBy({ id });\n if (!current) {\n throw new EntityNotFoundError();\n }\n\n // The lock is re-checked against the FRESH row: a rename\n // racing a concurrent nameLocked flip must still lose.\n const { name: currentName, nameLocked: currentNameLocked } = current;\n const merged = repository.merge(current, patch);\n if (currentNameLocked && patch.name && validated.nameLocked !== false) {\n merged.name = currentName;\n }\n\n return repository.save(merged);\n });\n\n return {\n entity,\n created: false, \n };\n }\n\n if (!validated.realmId) {\n const actorRealmId = this.getActorRealmId(actor);\n if (actorRealmId) {\n validated.realmId = actorRealmId;\n }\n }\n\n entity = this.repository.create(validated);\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_CREATE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity, ...this.resourceRealmMatch(entity) }),\n });\n\n if (validated.password) {\n entity.password = await credentialsService.protect(validated.password);\n }\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: true, \n };\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<User> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_DELETE });\n\n if (\n actor.identity &&\n actor.identity.type === 'user' &&\n actor.identity.data.id === id\n ) {\n throw new ValidationError('The own user can not be deleted.');\n }\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_DELETE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity, ...this.resourceRealmMatch(entity) }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n}\n"],"mappings":"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"}
@@ -8,6 +8,18 @@ export interface IUserRepository extends IEntityRepository<User> {
8
8
  findOneByWithEmail(where: Record<string, any>): Promise<User | null>;
9
9
  getBoundRoles(entity: string | User): Promise<Role[]>;
10
10
  getBoundPermissions(entity: string | User): Promise<PermissionPolicyBinding[]>;
11
+ /**
12
+ * Runs `fn` inside one database transaction. Single-row reads on the
13
+ * handed-in repository (`findOneBy`) are taken FOR UPDATE where the
14
+ * driver supports it and `save` commits with the callback, so a
15
+ * read-modify-write across the three calls cannot revert a concurrent
16
+ * write (#3526). Keep the callback to calls on the handed-in repository:
17
+ * the transaction pins one pooled connection, and anything else that
18
+ * reaches the DataSource (the permission evaluator, `validateJoinColumns`,
19
+ * `checkUniqueness`) takes a second one, which exhausts the pool under
20
+ * concurrent saves.
21
+ */
22
+ transaction<R>(fn: (repository: IUserRepository) => Promise<R>): Promise<R>;
11
23
  }
12
24
  export interface IUserService {
13
25
  getMany(query: Record<string, any>, actor: ActorContext): Promise<EntityRepositoryFindManyResult<User>>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/user/types.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAE,iBAAiB,EAAG,MAAM,oBAAoB,CAAC;AAE3G,MAAM,WAAW,eAAgB,SAAQ,iBAAiB,CAAC,IAAI,CAAC;IAC5D,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAE1E,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAErE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAEtD,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC;CAClF;AAED,MAAM,WAAW,YAAY;IACzB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC,CAAC;IACxG,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5G,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxF,IAAI,CACA,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,GACnC,OAAO,CAAC;QACP,MAAM,EAAE,IAAI,CAAC;QACb,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/user/types.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAE,iBAAiB,EAAG,MAAM,oBAAoB,CAAC;AAE3G,MAAM,WAAW,eAAgB,SAAQ,iBAAiB,CAAC,IAAI,CAAC;IAC5D,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAE1E,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAErE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAEtD,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC;IAE/E;;;;;;;;;;OAUG;IACH,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC/E;AAED,MAAM,WAAW,YAAY;IACzB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC,CAAC;IACxG,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5G,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxF,IAAI,CACA,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,GACnC,OAAO,CAAC;QACP,MAAM,EAAE,IAAI,CAAC;QACb,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D"}
@@ -99,7 +99,7 @@ var UserPermissionService = class extends JunctionEntityService {
99
99
  let actorScope = RealmScope.ANY;
100
100
  let actorPolicyFree = true;
101
101
  let actorPolicyId = null;
102
- if (actor.identity && permission) {
102
+ if (permission && actor.identity) {
103
103
  const grant = await this.identityPermissionProvider.resolveJunctionGrant({
104
104
  type: actor.identity.type,
105
105
  id: actor.identity.data.id
@@ -1 +1 @@
1
- {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","RealmScope","definePolicyData","EntityConflictError","EntityNotFoundError","ValidatorGroup","PermissionName","UserPermissionValidator","applyJunctionCreateGrant","buildJunctionUpdateData","JunctionEntityService","decodeQuery","userPermissionSchema","UserPermissionService","ownerRealmKey","repository","permissionRepository","identityPermissionProvider","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","USER_PERMISSION_CREATE","USER_PERMISSION_DELETE","USER_PERMISSION_READ","findMany","schema","getOne","id","entity","findOneBy","create","data","preEvaluate","validated","run","group","CREATE","validateJoinColumns","existing","permissionId","userId","permission","permissionRealmId","realmId","clientId","user","userRealmId","identity","grant","resolveJunctionGrant","type","realmScope","OWN","evaluate","ATTRIBUTES","junctionAttributes","REALM_MATCH","junctionResourceRealm","save","update","USER_PERMISSION_UPDATE","UPDATE","findOneById","actorScope","ANY","actorPolicyFree","actorPolicyId","policy","updateData","existingScope","merged","merge","delete","entityId","remove"],"sources":["../../../../src/core/entities/user-permission/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n BuiltInPolicyType,\n RealmScope,\n definePolicyData,\n} from '@authup/access';\nimport { EntityConflictError, EntityNotFoundError } from '@authup/errors';\nimport { ValidatorGroup } from '@authup/kit';\nimport { PermissionName, UserPermissionValidator } from '@authup/core-kit';\nimport type { Permission, UserPermission } from '@authup/core-kit';\nimport type { IIdentityPermissionProvider } from '../../identity/permission/types.ts';\nimport { applyJunctionCreateGrant, buildJunctionUpdateData } from '../../identity/permission/junction-grant.ts';\nimport type { ActorContext, EntityRepositoryFindManyResult, IEntityRepository } from '@authup/server-kit';\nimport { JunctionEntityService } from '@authup/server-kit';\nimport type { IUserPermissionRepository, IUserPermissionService } from './types.ts';\nimport { decodeQuery } from '../../query/index.ts';\nimport { userPermissionSchema } from './schema.ts';\n\nexport type UserPermissionServiceContext = {\n repository: IUserPermissionRepository;\n permissionRepository: IEntityRepository<Permission>;\n identityPermissionProvider: IIdentityPermissionProvider;\n};\n\nexport class UserPermissionService extends JunctionEntityService implements IUserPermissionService {\n protected readonly ownerRealmKey = 'userRealmId';\n\n protected repository: IUserPermissionRepository;\n\n protected permissionRepository: IEntityRepository<Permission>;\n\n protected identityPermissionProvider: IIdentityPermissionProvider;\n\n protected validator: UserPermissionValidator;\n\n constructor(ctx: UserPermissionServiceContext) {\n super();\n this.repository = ctx.repository;\n this.permissionRepository = ctx.permissionRepository;\n this.identityPermissionProvider = ctx.identityPermissionProvider;\n this.validator = new UserPermissionValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<UserPermission>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.USER_PERMISSION_CREATE,\n PermissionName.USER_PERMISSION_DELETE,\n PermissionName.USER_PERMISSION_READ,\n ],\n });\n\n return this.repository.findMany(await decodeQuery(query, { schema: userPermissionSchema, actor }));\n }\n\n async getOne(\n id: string,\n actor: ActorContext,\n ): Promise<UserPermission> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.USER_PERMISSION_CREATE,\n PermissionName.USER_PERMISSION_DELETE,\n PermissionName.USER_PERMISSION_READ,\n ],\n });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<UserPermission> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_PERMISSION_CREATE });\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.CREATE });\n\n await this.repository.validateJoinColumns(validated);\n\n const existing = await this.repository.findOneBy({\n permissionId: validated.permissionId,\n userId: validated.userId,\n });\n if (existing) {\n throw new EntityConflictError({ entity: 'user-permission' });\n }\n\n if (validated.permission) {\n validated.permissionRealmId = validated.permission.realmId;\n\n await actor.permissionEvaluator.preEvaluate({\n name: validated.permission.name,\n realmId: validated.permission.realmId,\n clientId: validated.permission.clientId,\n });\n }\n\n if (validated.user) {\n validated.userRealmId = validated.user.realmId;\n }\n\n if (validated.permission && actor.identity) {\n const grant = await this.identityPermissionProvider.resolveJunctionGrant(\n {\n type: actor.identity.type,\n id: actor.identity.data.id,\n },\n {\n name: validated.permission.name,\n realmId: validated.permission.realmId,\n clientId: validated.permission.clientId,\n realmScope: validated.realmScope ?? RealmScope.OWN,\n },\n );\n\n applyJunctionCreateGrant(validated, grant);\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_PERMISSION_CREATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(validated),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(validated),\n }),\n });\n\n let entity = this.repository.create(validated);\n entity = await this.repository.save(entity);\n\n return entity;\n }\n\n async update(\n id: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<UserPermission> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_PERMISSION_UPDATE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.UPDATE });\n\n const permission = await this.permissionRepository.findOneById(entity.permissionId);\n if (permission) {\n // Member-permission gate: an actor may only modify a binding for a permission it\n // holds (mirrors create()).\n await actor.permissionEvaluator.preEvaluate({\n name: permission.name,\n realmId: permission.realmId,\n clientId: permission.clientId,\n });\n }\n\n let actorScope: `${RealmScope}` = RealmScope.ANY;\n let actorPolicyFree = true;\n let actorPolicyId: string | null = null;\n if (actor.identity && permission) {\n const grant = await this.identityPermissionProvider.resolveJunctionGrant(\n { type: actor.identity.type, id: actor.identity.data.id },\n {\n name: permission.name,\n realmId: permission.realmId,\n clientId: permission.clientId,\n realmScope: validated.realmScope ?? entity.realmScope,\n },\n );\n actorScope = grant.realmScope;\n actorPolicyFree = !grant.policy;\n actorPolicyId = grant.policy ? grant.policy.id : null;\n } else if (actor.identity) {\n actorScope = RealmScope.OWN;\n }\n\n const updateData = buildJunctionUpdateData({\n data: validated,\n existingScope: entity.realmScope,\n actorScope,\n actorPolicyFree,\n actorPolicyId,\n });\n\n await this.repository.validateJoinColumns(updateData);\n\n const merged = this.repository.merge(entity, updateData);\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_PERMISSION_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(merged),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(merged),\n }),\n });\n\n return this.repository.save(merged);\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<UserPermission> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_PERMISSION_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_PERMISSION_DELETE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(entity),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(entity),\n }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","RealmScope","definePolicyData","EntityConflictError","EntityNotFoundError","ValidatorGroup","PermissionName","UserPermissionValidator","applyJunctionCreateGrant","buildJunctionUpdateData","JunctionEntityService","decodeQuery","userPermissionSchema","UserPermissionService","ownerRealmKey","repository","permissionRepository","identityPermissionProvider","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","USER_PERMISSION_CREATE","USER_PERMISSION_DELETE","USER_PERMISSION_READ","findMany","schema","getOne","id","entity","findOneBy","create","data","preEvaluate","validated","run","group","CREATE","validateJoinColumns","existing","permissionId","userId","permission","permissionRealmId","realmId","clientId","user","userRealmId","identity","grant","resolveJunctionGrant","type","realmScope","OWN","evaluate","ATTRIBUTES","junctionAttributes","REALM_MATCH","junctionResourceRealm","save","update","USER_PERMISSION_UPDATE","UPDATE","findOneById","actorScope","ANY","actorPolicyFree","actorPolicyId","policy","updateData","existingScope","merged","merge","delete","entityId","remove"],"sources":["../../../../src/core/entities/user-permission/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n BuiltInPolicyType,\n RealmScope,\n definePolicyData,\n} from '@authup/access';\nimport { EntityConflictError, EntityNotFoundError } from '@authup/errors';\nimport { ValidatorGroup } from '@authup/kit';\nimport { PermissionName, UserPermissionValidator } from '@authup/core-kit';\nimport type { Permission, UserPermission } from '@authup/core-kit';\nimport type { IIdentityPermissionProvider } from '../../identity/permission/types.ts';\nimport { applyJunctionCreateGrant, buildJunctionUpdateData } from '../../identity/permission/junction-grant.ts';\nimport type { ActorContext, EntityRepositoryFindManyResult, IEntityRepository } from '@authup/server-kit';\nimport { JunctionEntityService } from '@authup/server-kit';\nimport type { IUserPermissionRepository, IUserPermissionService } from './types.ts';\nimport { decodeQuery } from '../../query/index.ts';\nimport { userPermissionSchema } from './schema.ts';\n\nexport type UserPermissionServiceContext = {\n repository: IUserPermissionRepository;\n permissionRepository: IEntityRepository<Permission>;\n identityPermissionProvider: IIdentityPermissionProvider;\n};\n\nexport class UserPermissionService extends JunctionEntityService implements IUserPermissionService {\n protected readonly ownerRealmKey = 'userRealmId';\n\n protected repository: IUserPermissionRepository;\n\n protected permissionRepository: IEntityRepository<Permission>;\n\n protected identityPermissionProvider: IIdentityPermissionProvider;\n\n protected validator: UserPermissionValidator;\n\n constructor(ctx: UserPermissionServiceContext) {\n super();\n this.repository = ctx.repository;\n this.permissionRepository = ctx.permissionRepository;\n this.identityPermissionProvider = ctx.identityPermissionProvider;\n this.validator = new UserPermissionValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<UserPermission>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.USER_PERMISSION_CREATE,\n PermissionName.USER_PERMISSION_DELETE,\n PermissionName.USER_PERMISSION_READ,\n ],\n });\n\n return this.repository.findMany(await decodeQuery(query, { schema: userPermissionSchema, actor }));\n }\n\n async getOne(\n id: string,\n actor: ActorContext,\n ): Promise<UserPermission> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.USER_PERMISSION_CREATE,\n PermissionName.USER_PERMISSION_DELETE,\n PermissionName.USER_PERMISSION_READ,\n ],\n });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<UserPermission> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_PERMISSION_CREATE });\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.CREATE });\n\n await this.repository.validateJoinColumns(validated);\n\n const existing = await this.repository.findOneBy({\n permissionId: validated.permissionId,\n userId: validated.userId,\n });\n if (existing) {\n throw new EntityConflictError({ entity: 'user-permission' });\n }\n\n if (validated.permission) {\n validated.permissionRealmId = validated.permission.realmId;\n\n await actor.permissionEvaluator.preEvaluate({\n name: validated.permission.name,\n realmId: validated.permission.realmId,\n clientId: validated.permission.clientId,\n });\n }\n\n if (validated.user) {\n validated.userRealmId = validated.user.realmId;\n }\n\n if (validated.permission && actor.identity) {\n const grant = await this.identityPermissionProvider.resolveJunctionGrant(\n {\n type: actor.identity.type,\n id: actor.identity.data.id,\n },\n {\n name: validated.permission.name,\n realmId: validated.permission.realmId,\n clientId: validated.permission.clientId,\n realmScope: validated.realmScope ?? RealmScope.OWN,\n },\n );\n\n applyJunctionCreateGrant(validated, grant);\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_PERMISSION_CREATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(validated),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(validated),\n }),\n });\n\n let entity = this.repository.create(validated);\n entity = await this.repository.save(entity);\n\n return entity;\n }\n\n async update(\n id: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<UserPermission> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_PERMISSION_UPDATE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.UPDATE });\n\n const permission = await this.permissionRepository.findOneById(entity.permissionId);\n if (permission) {\n // Member-permission gate: an actor may only modify a binding for a permission it\n // holds (mirrors create()).\n await actor.permissionEvaluator.preEvaluate({\n name: permission.name,\n realmId: permission.realmId,\n clientId: permission.clientId,\n });\n }\n\n let actorScope: `${RealmScope}` = RealmScope.ANY;\n let actorPolicyFree = true;\n let actorPolicyId: string | null = null;\n if (permission && actor.identity) {\n const grant = await this.identityPermissionProvider.resolveJunctionGrant(\n { type: actor.identity.type, id: actor.identity.data.id },\n {\n name: permission.name,\n realmId: permission.realmId,\n clientId: permission.clientId,\n realmScope: validated.realmScope ?? entity.realmScope,\n },\n );\n actorScope = grant.realmScope;\n actorPolicyFree = !grant.policy;\n actorPolicyId = grant.policy ? grant.policy.id : null;\n } else if (actor.identity) {\n actorScope = RealmScope.OWN;\n }\n\n const updateData = buildJunctionUpdateData({\n data: validated,\n existingScope: entity.realmScope,\n actorScope,\n actorPolicyFree,\n actorPolicyId,\n });\n\n await this.repository.validateJoinColumns(updateData);\n\n const merged = this.repository.merge(entity, updateData);\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_PERMISSION_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(merged),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(merged),\n }),\n });\n\n return this.repository.save(merged);\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<UserPermission> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_PERMISSION_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_PERMISSION_DELETE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(entity),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(entity),\n }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n}\n"],"mappings":"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"}
@@ -5,6 +5,7 @@ import { applyJunctionCreateGrant, buildJunctionUpdateData } from "./permission/
5
5
  import { toIdentityPolicyData } from "./permission/identity-policy-data.mjs";
6
6
  import { IdentityProviderLdapAuthenticator } from "./provider/authentication/protocols/ldap/module.mjs";
7
7
  import { IdentityProviderLdapCollectionAuthenticator } from "./provider/authentication/protocols/ldap/collection.mjs";
8
+ import { IDENTITY_PROVIDER_ASSURANCE_ERROR_INSTANCE, IdentityProviderAssuranceError, assertIdentityProviderAssurance, buildIdentityProviderAcrValues, isIdentityProviderAssuranceError } from "./provider/authentication/protocols/oauth2/assurance.mjs";
8
9
  import { IdentityProviderOAuth2Authenticator } from "./provider/authentication/protocols/oauth2/module.mjs";
9
10
  import { IdentityProviderOpenIDAuthenticator } from "./provider/authentication/protocols/open-id/module.mjs";
10
11
  import { IdentityProviderFacebookAuthenticator } from "./provider/authentication/presets/facebook.mjs";
@@ -36,4 +37,4 @@ import "./registration/index.mjs";
36
37
  import { IdentityResolver } from "./resolver/module.mjs";
37
38
  import "./resolver/index.mjs";
38
39
  import { IdentityRoleProvider } from "./role/module.mjs";
39
- export { IDENTITY_PROVIDER_ACCOUNT_ALREADY_LINKED_ERROR_INSTANCE, IDENTITY_PROVIDER_ACCOUNT_LINK_TTL, IDENTITY_PROVIDER_LDAP_COLLECTION_AUTHENTICATOR_TOKEN, IdentityPermissionProvider, IdentityProviderAccountAlreadyLinkedError, IdentityProviderAccountBaseMapper, IdentityProviderAccountManager, IdentityProviderAttributeMapper, IdentityProviderFacebookAuthenticator, IdentityProviderGithubAuthenticator, IdentityProviderGoogleAuthenticator, IdentityProviderInstagramAuthenticator, IdentityProviderLdapAuthenticator, IdentityProviderLdapCollectionAuthenticator, IdentityProviderMapperOperation, IdentityProviderOAuth2Authenticator, IdentityProviderOpenIDAuthenticator, IdentityProviderPaypalAuthenticator, IdentityProviderPermissionMapper, IdentityProviderRoleMapper, IdentityResolver, IdentityRoleProvider, PASSWORD_RESET_EXPIRES_IN_MINUTES, PasswordRecoveryService, PermissionCheckerService, PolicyCheckerService, RegistrationService, applyJunctionCreateGrant, buildJunctionUpdateData, createIdentityProviderOAuth2Authenticator, isIdentityProviderAccountAlreadyLinkedError, toIdentityPolicyData };
40
+ export { IDENTITY_PROVIDER_ACCOUNT_ALREADY_LINKED_ERROR_INSTANCE, IDENTITY_PROVIDER_ACCOUNT_LINK_TTL, IDENTITY_PROVIDER_ASSURANCE_ERROR_INSTANCE, IDENTITY_PROVIDER_LDAP_COLLECTION_AUTHENTICATOR_TOKEN, IdentityPermissionProvider, IdentityProviderAccountAlreadyLinkedError, IdentityProviderAccountBaseMapper, IdentityProviderAccountManager, IdentityProviderAssuranceError, IdentityProviderAttributeMapper, IdentityProviderFacebookAuthenticator, IdentityProviderGithubAuthenticator, IdentityProviderGoogleAuthenticator, IdentityProviderInstagramAuthenticator, IdentityProviderLdapAuthenticator, IdentityProviderLdapCollectionAuthenticator, IdentityProviderMapperOperation, IdentityProviderOAuth2Authenticator, IdentityProviderOpenIDAuthenticator, IdentityProviderPaypalAuthenticator, IdentityProviderPermissionMapper, IdentityProviderRoleMapper, IdentityResolver, IdentityRoleProvider, PASSWORD_RESET_EXPIRES_IN_MINUTES, PasswordRecoveryService, PermissionCheckerService, PolicyCheckerService, RegistrationService, applyJunctionCreateGrant, assertIdentityProviderAssurance, buildIdentityProviderAcrValues, buildJunctionUpdateData, createIdentityProviderOAuth2Authenticator, isIdentityProviderAccountAlreadyLinkedError, isIdentityProviderAssuranceError, toIdentityPolicyData };
@@ -43,7 +43,7 @@ import { RealmScope, minRealmScope } from "@authup/access";
43
43
  const touchesScope = hasOwnProperty(data, "realmScope");
44
44
  const touchesPolicy = hasOwnProperty(data, "policyId");
45
45
  if (touchesScope) updateData.realmScope = minRealmScope([data.realmScope, actorScope]);
46
- if (actorScope === RealmScope.ANY && actorPolicyFree) {
46
+ if (actorPolicyFree && actorScope === RealmScope.ANY) {
47
47
  if (touchesPolicy) updateData.policyId = data.policyId;
48
48
  } else if (touchesScope || touchesPolicy) {
49
49
  updateData.policyId = actorPolicyId;
@@ -1 +1 @@
1
- {"version":3,"file":"junction-grant.mjs","names":["RealmScope","minRealmScope","hasOwnProperty","applyJunctionCreateGrant","validated","grant","realmScope","OWN","ANY","policy","policyId","id","buildJunctionUpdateData","input","data","existingScope","actorScope","actorPolicyFree","actorPolicyId","updateData","touchesScope","touchesPolicy"],"sources":["../../../../src/core/identity/permission/junction-grant.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 { RealmScope, minRealmScope } from '@authup/access';\nimport { hasOwnProperty } from '@authup/kit';\nimport type { ResolveJunctionGrantResult } from './types.ts';\n\n/**\n * The privilege-escalation boundary for permission-binding junctions, shared verbatim by\n * role/user/client-permission. Kept in ONE place (rather than copied into each service)\n * so the fail-closed cap/inherit rule is audited and changed once — see #3160 / #3158 / #3159,\n * which each had to patch this rule across all four services.\n *\n * It depends on a server-core type (`ResolveJunctionGrantResult`) and so cannot live on the\n * generic `JunctionEntityService` in `@authup/server-kit` (that would invert the layering).\n */\n\n/**\n * Cap a junction CREATE to the actor's request-relative selected grant and inherit its policy.\n *\n * - `realmScope` is capped to the actor's selected reach (`min(requested, grant.realmScope)`).\n * - The policy follows the grant: only a genuinely unrestricted actor (an UNCAPPED `any` reach\n * AND no policy) may keep an explicitly-requested `policyId`; any restricted/policy-bound\n * actor inherits its own grant's policy (it can neither attach an unowned policy nor detach to\n * widen). The check reads `grant.realmScope` UNCAPPED precisely to distinguish that case — the\n * grant is returned uncapped by `resolveJunctionGrant` for exactly this reason.\n *\n * Mutates `validated` in place (mirrors the surrounding service style).\n */\nexport function applyJunctionCreateGrant(\n validated: Record<string, any>,\n grant: ResolveJunctionGrantResult,\n): void {\n validated.realmScope = minRealmScope([validated.realmScope ?? RealmScope.OWN, grant.realmScope]);\n\n if (grant.realmScope !== RealmScope.ANY || grant.policy) {\n validated.policyId = grant.policy ? grant.policy.id : null;\n }\n}\n\nexport type BuildJunctionUpdateDataInput = {\n /** The validated update payload (UPDATE group) — presence of a key signals caller intent. */\n data: Record<string, any>,\n /** The persisted junction's current reach (used to re-cap a policy-only edit). */\n existingScope: `${RealmScope}`,\n /** The actor's UNCAPPED selected reach for this permission (`any` for system context). */\n actorScope: `${RealmScope}`,\n /** Whether the actor's selected grant carries no policy. */\n actorPolicyFree: boolean,\n /** The id of the actor's selected grant policy (null when policy-free). */\n actorPolicyId: string | null,\n};\n\n/**\n * Build the `{ realmScope?, policyId? }` delta for a junction UPDATE, capped to the actor's\n * request-relative grant.\n *\n * - An unrestricted (`any`, policy-free) actor may set/clear `policyId` explicitly and is never\n * narrowed.\n * - A restricted/policy-bound actor that touches the binding inherits its own grant's policy AND\n * has the reach re-capped — including the EXISTING `realmScope` when the update omits it, so a\n * policy-only edit cannot leave a wider pre-existing reach standing (fail-OPEN otherwise: the\n * persisted binding must always be dominated by a grant the actor really holds — #3160).\n */\nexport function buildJunctionUpdateData(input: BuildJunctionUpdateDataInput): Record<string, any> {\n const {\n data, \n existingScope, \n actorScope, \n actorPolicyFree, \n actorPolicyId,\n } = input;\n\n const updateData: Record<string, any> = {};\n\n const touchesScope = hasOwnProperty(data, 'realmScope');\n const touchesPolicy = hasOwnProperty(data, 'policyId');\n\n // CAP to the actor's ceiling — a restricted actor may narrow but never widen.\n // (`data` is the validated UPDATE payload, so realmScope is already a valid enum value;\n // minRealmScope additionally normalizes any out-of-band input fail-closed to `own`.)\n if (touchesScope) {\n updateData.realmScope = minRealmScope([data.realmScope as `${RealmScope}`, actorScope]);\n }\n\n if (actorScope === RealmScope.ANY && actorPolicyFree) {\n if (touchesPolicy) {\n updateData.policyId = data.policyId;\n }\n } else if (touchesScope || touchesPolicy) {\n updateData.policyId = actorPolicyId;\n\n if (!touchesScope) {\n updateData.realmScope = minRealmScope([existingScope, actorScope]);\n }\n }\n\n return updateData;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;GAiCA,SAAgBG,yBACZC,WACAC,OAAiC;CAEjCD,UAAUE,aAAaL,cAAc,CAACG,UAAUE,cAAcN,WAAWO,KAAKF,MAAMC,UAAW,CAAA;CAE/F,IAAID,MAAMC,eAAeN,WAAWQ,OAAOH,MAAMI,QAC7CL,UAAUM,WAAWL,MAAMI,SAASJ,MAAMI,OAAOE,KAAK;AAE9D;;;;;;;;;;;GA0BA,SAAgBC,wBAAwBC,OAAmC;CACvE,MAAM,EACFC,MACAC,eACAC,YACAC,iBACAC,kBACAL;CAEJ,MAAMM,aAAkC,CAAC;CAEzC,MAAMC,eAAelB,eAAeY,MAAM,YAAA;CAC1C,MAAMO,gBAAgBnB,eAAeY,MAAM,UAAA;CAK3C,IAAIM,cACAD,WAAWb,aAAaL,cAAc,CAACa,KAAKR,YAA+BU,UAAW,CAAA;CAG1F,IAAIA,eAAehB,WAAWQ,OAAOS,iBAC7BI;MAAAA,eACAF,WAAWT,WAAWI,KAAKJ;CAAAA,OAE5B,IAAIU,gBAAgBC,eAAe;EACtCF,WAAWT,WAAWQ;EAEtB,IAAI,CAACE,cACDD,WAAWb,aAAaL,cAAc,CAACc,eAAeC,UAAW,CAAA;CAEzE;CAEA,OAAOG;AACX"}
1
+ {"version":3,"file":"junction-grant.mjs","names":["RealmScope","minRealmScope","hasOwnProperty","applyJunctionCreateGrant","validated","grant","realmScope","OWN","ANY","policy","policyId","id","buildJunctionUpdateData","input","data","existingScope","actorScope","actorPolicyFree","actorPolicyId","updateData","touchesScope","touchesPolicy"],"sources":["../../../../src/core/identity/permission/junction-grant.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 { RealmScope, minRealmScope } from '@authup/access';\nimport { hasOwnProperty } from '@authup/kit';\nimport type { ResolveJunctionGrantResult } from './types.ts';\n\n/**\n * The privilege-escalation boundary for permission-binding junctions, shared verbatim by\n * role/user/client-permission. Kept in ONE place (rather than copied into each service)\n * so the fail-closed cap/inherit rule is audited and changed once — see #3160 / #3158 / #3159,\n * which each had to patch this rule across all four services.\n *\n * It depends on a server-core type (`ResolveJunctionGrantResult`) and so cannot live on the\n * generic `JunctionEntityService` in `@authup/server-kit` (that would invert the layering).\n */\n\n/**\n * Cap a junction CREATE to the actor's request-relative selected grant and inherit its policy.\n *\n * - `realmScope` is capped to the actor's selected reach (`min(requested, grant.realmScope)`).\n * - The policy follows the grant: only a genuinely unrestricted actor (an UNCAPPED `any` reach\n * AND no policy) may keep an explicitly-requested `policyId`; any restricted/policy-bound\n * actor inherits its own grant's policy (it can neither attach an unowned policy nor detach to\n * widen). The check reads `grant.realmScope` UNCAPPED precisely to distinguish that case — the\n * grant is returned uncapped by `resolveJunctionGrant` for exactly this reason.\n *\n * Mutates `validated` in place (mirrors the surrounding service style).\n */\nexport function applyJunctionCreateGrant(\n validated: Record<string, any>,\n grant: ResolveJunctionGrantResult,\n): void {\n validated.realmScope = minRealmScope([validated.realmScope ?? RealmScope.OWN, grant.realmScope]);\n\n if (grant.realmScope !== RealmScope.ANY || grant.policy) {\n validated.policyId = grant.policy ? grant.policy.id : null;\n }\n}\n\nexport type BuildJunctionUpdateDataInput = {\n /** The validated update payload (UPDATE group) — presence of a key signals caller intent. */\n data: Record<string, any>,\n /** The persisted junction's current reach (used to re-cap a policy-only edit). */\n existingScope: `${RealmScope}`,\n /** The actor's UNCAPPED selected reach for this permission (`any` for system context). */\n actorScope: `${RealmScope}`,\n /** Whether the actor's selected grant carries no policy. */\n actorPolicyFree: boolean,\n /** The id of the actor's selected grant policy (null when policy-free). */\n actorPolicyId: string | null,\n};\n\n/**\n * Build the `{ realmScope?, policyId? }` delta for a junction UPDATE, capped to the actor's\n * request-relative grant.\n *\n * - An unrestricted (`any`, policy-free) actor may set/clear `policyId` explicitly and is never\n * narrowed.\n * - A restricted/policy-bound actor that touches the binding inherits its own grant's policy AND\n * has the reach re-capped — including the EXISTING `realmScope` when the update omits it, so a\n * policy-only edit cannot leave a wider pre-existing reach standing (fail-OPEN otherwise: the\n * persisted binding must always be dominated by a grant the actor really holds — #3160).\n */\nexport function buildJunctionUpdateData(input: BuildJunctionUpdateDataInput): Record<string, any> {\n const {\n data, \n existingScope, \n actorScope, \n actorPolicyFree, \n actorPolicyId,\n } = input;\n\n const updateData: Record<string, any> = {};\n\n const touchesScope = hasOwnProperty(data, 'realmScope');\n const touchesPolicy = hasOwnProperty(data, 'policyId');\n\n // CAP to the actor's ceiling — a restricted actor may narrow but never widen.\n // (`data` is the validated UPDATE payload, so realmScope is already a valid enum value;\n // minRealmScope additionally normalizes any out-of-band input fail-closed to `own`.)\n if (touchesScope) {\n updateData.realmScope = minRealmScope([data.realmScope as `${RealmScope}`, actorScope]);\n }\n\n if (actorPolicyFree && actorScope === RealmScope.ANY) {\n if (touchesPolicy) {\n updateData.policyId = data.policyId;\n }\n } else if (touchesScope || touchesPolicy) {\n updateData.policyId = actorPolicyId;\n\n if (!touchesScope) {\n updateData.realmScope = minRealmScope([existingScope, actorScope]);\n }\n }\n\n return updateData;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;GAiCA,SAAgBG,yBACZC,WACAC,OAAiC;CAEjCD,UAAUE,aAAaL,cAAc,CAACG,UAAUE,cAAcN,WAAWO,KAAKF,MAAMC,UAAW,CAAA;CAE/F,IAAID,MAAMC,eAAeN,WAAWQ,OAAOH,MAAMI,QAC7CL,UAAUM,WAAWL,MAAMI,SAASJ,MAAMI,OAAOE,KAAK;AAE9D;;;;;;;;;;;GA0BA,SAAgBC,wBAAwBC,OAAmC;CACvE,MAAM,EACFC,MACAC,eACAC,YACAC,iBACAC,kBACAL;CAEJ,MAAMM,aAAkC,CAAC;CAEzC,MAAMC,eAAelB,eAAeY,MAAM,YAAA;CAC1C,MAAMO,gBAAgBnB,eAAeY,MAAM,UAAA;CAK3C,IAAIM,cACAD,WAAWb,aAAaL,cAAc,CAACa,KAAKR,YAA+BU,UAAW,CAAA;CAG1F,IAAIC,mBAAmBD,eAAehB,WAAWQ,KACzCa;MAAAA,eACAF,WAAWT,WAAWI,KAAKJ;CAAAA,OAE5B,IAAIU,gBAAgBC,eAAe;EACtCF,WAAWT,WAAWQ;EAEtB,IAAI,CAACE,cACDD,WAAWb,aAAaL,cAAc,CAACc,eAAeC,UAAW,CAAA;CAEzE;CAEA,OAAOG;AACX"}
@@ -1,9 +1,9 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- import { IdentityProviderAccountAlreadyLinkedError } from "./error.mjs";
5
4
  import { describeError } from "../../../../utils/error.mjs";
6
5
  import "../../../../utils/index.mjs";
6
+ import { IdentityProviderAccountAlreadyLinkedError } from "./error.mjs";
7
7
  import { IdentityProviderIdentityOperation } from "../constants.mjs";
8
8
  import { IdentityProviderMapperOperation } from "../mapper/constants.mjs";
9
9
  import "../mapper/index.mjs";
@@ -173,7 +173,7 @@ var IdentityProviderAccountManager = class {
173
173
  retry = true;
174
174
  break;
175
175
  }
176
- if (entity.name && pathNormalized === "email") {
176
+ if (pathNormalized === "email" && entity.name) {
177
177
  entity[pathNormalized] = buildUserFakeEmail(entity.name);
178
178
  retry = true;
179
179
  break;
@@ -1 +1 @@
1
- {"version":3,"file":"module.mjs","names":["UserValidator","buildUserFakeEmail","isUserFakeEmail","ValidatorGroup","createNanoID","extendObject","ValidationError","isEntityConflictError","isValidupError","stringifyPath","describeError","IdentityProviderIdentityOperation","IdentityProviderMapperOperation","IdentityProviderAccountAlreadyLinkedError","IdentityProviderAccountManager","attributesMapper","permissionMapper","roleMapper","repository","userRepository","userValidator","logger","ctx","attributeMapper","save","identity","account","findOneByProviderIdentity","update","operation","CREATE","user","saveUser","providerId","provider","id","providerUserId","providerUserName","name","providerRealmId","realmId","userId","userRealmId","e","raced","remove","removeError","warn","saveRoles","savePermissions","UPDATE","link","findOneById","pickCandidate","slice","providerUserEmail","existing","undefined","key","maxLength","candidates","attributeCandidates","candidate","length","attributes","execute","entity","attribute","value","active","nameLocked","clientId","attributesSelf","validateAttributes","Error","attributesSelfKeys","Object","keys","attributesExtra","entityKeys","entityKey","index","indexOf","output","trim","toLowerCase","attempts","Math","max","saveOneWithEA","names","shift","run","group","email","retry","i","issues","child","pathNormalized","path","Array","isArray","first","rest","push","entities"],"sources":["../../../../../src/core/identity/provider/account/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 { IdentityProviderAccount, User } from '@authup/core-kit';\nimport {\n UserValidator,\n buildUserFakeEmail,\n isUserFakeEmail,\n} from '@authup/core-kit';\nimport { ValidatorGroup, createNanoID, extendObject } from '@authup/kit';\nimport { ValidationError, isEntityConflictError } from '@authup/errors';\nimport { isValidupError, stringifyPath } from 'validup';\nimport type { Logger } from '@authup/server-kit';\nimport { describeError } from '../../../../utils/index.ts';\nimport type { IUserIdentityRepository } from '../../entities/index.ts';\nimport { IdentityProviderIdentityOperation } from '../constants.ts';\nimport type { IIdentityProviderMapper } from '../mapper/index.ts';\nimport { IdentityProviderMapperOperation } from '../mapper/index.ts';\nimport type { IdentityProviderIdentity } from '../types.ts';\nimport { IdentityProviderAccountAlreadyLinkedError } from './error.ts';\nimport type { IIdentityProviderAccountManager, IIdentityProviderAccountRepository, IdentityProviderAccountManagerContext } from './types.ts';\n\nexport class IdentityProviderAccountManager implements IIdentityProviderAccountManager {\n protected attributesMapper : IIdentityProviderMapper;\n\n protected permissionMapper : IIdentityProviderMapper;\n\n protected roleMapper : IIdentityProviderMapper;\n\n protected repository : IIdentityProviderAccountRepository;\n\n protected userRepository: IUserIdentityRepository;\n\n protected userValidator : UserValidator;\n\n protected logger?: Logger;\n\n constructor(ctx: IdentityProviderAccountManagerContext) {\n this.attributesMapper = ctx.attributeMapper;\n this.permissionMapper = ctx.permissionMapper;\n this.roleMapper = ctx.roleMapper;\n this.repository = ctx.repository;\n this.userRepository = ctx.userRepository;\n this.logger = ctx.logger;\n\n this.userValidator = new UserValidator();\n }\n\n async save(identity: IdentityProviderIdentity): Promise<IdentityProviderAccount> {\n let account = await this.repository.findOneByProviderIdentity(identity);\n if (account) {\n return this.update(identity, account);\n }\n\n identity.operation = IdentityProviderIdentityOperation.CREATE;\n\n const user = await this.saveUser(identity);\n\n try {\n account = await this.repository.save({\n providerId: identity.provider.id,\n providerUserId: identity.id,\n providerUserName: user.name, // todo: parse identity.name\n providerRealmId: identity.provider.realmId,\n user,\n userId: user.id,\n userRealmId: user.realmId,\n });\n } catch (e) {\n if (!isEntityConflictError(e)) {\n throw e;\n }\n\n // the loser of two concurrent first logins: the identity is linked\n // now, so continue with the winner's account and drop the user\n // this request provisioned moments ago (unreferenced; best effort,\n // a leftover row must not fail the login).\n const raced = await this.repository.findOneByProviderIdentity(identity);\n if (!raced) {\n throw e;\n }\n\n try {\n await this.userRepository.remove(user);\n } catch (removeError) {\n // The row is unreferenced, so it costs nothing but a squatted\n // user name. Left unreported it would be invisible forever.\n this.logger?.warn(describeError(\n removeError,\n `The user provisioned for the external identity \"${identity.id}\" could not be removed after losing a concurrent first login.`,\n ));\n }\n\n return this.update(identity, raced);\n }\n\n await this.saveRoles(identity, account.user);\n await this.savePermissions(identity, account.user);\n\n return account;\n }\n\n protected async update(\n identity: IdentityProviderIdentity,\n account: IdentityProviderAccount,\n ): Promise<IdentityProviderAccount> {\n identity.operation = IdentityProviderIdentityOperation.UPDATE;\n\n account.user = await this.saveUser(identity, account.user);\n\n await this.repository.save(account);\n\n await this.saveRoles(identity, account.user);\n await this.savePermissions(identity, account.user);\n\n return account;\n }\n\n async link(identity: IdentityProviderIdentity, userId: string): Promise<IdentityProviderAccount> {\n const user = await this.userRepository.findOneById(userId);\n if (!user) {\n throw new ValidationError('The linking user does not exist.');\n }\n\n if (\n identity.provider.realmId &&\n user.realmId !== identity.provider.realmId\n ) {\n throw new ValidationError('The provider and user realm do not match.');\n }\n\n const providerUserName = this.pickCandidate(identity, 'name', 256) ?? identity.id.slice(0, 256);\n const providerUserEmail = this.pickCandidate(identity, 'email', 512);\n\n const existing = await this.repository.findOneByProviderIdentity(identity);\n if (existing) {\n if (existing.userId !== userId) {\n throw new IdentityProviderAccountAlreadyLinkedError();\n }\n\n existing.providerUserName = providerUserName ?? existing.providerUserName;\n existing.providerUserEmail = providerUserEmail ?? existing.providerUserEmail;\n\n return this.repository.save(existing);\n }\n\n try {\n return await this.repository.save({\n providerId: identity.provider.id,\n providerUserId: identity.id,\n providerUserName,\n providerUserEmail: providerUserEmail ?? undefined,\n providerRealmId: identity.provider.realmId,\n userId,\n userRealmId: user.realmId ?? null,\n });\n } catch (e) {\n if (!isEntityConflictError(e)) {\n throw e;\n }\n\n // one of the two unique indexes fired; the re-read tells which:\n // a row for the identity means (providerUserId, providerId), a\n // race with the SAME user (two Connect tabs) being a no-op; no\n // row means (providerId, userId), the user already holds a link\n // at this provider through another external account.\n const raced = await this.repository.findOneByProviderIdentity(identity);\n if (raced) {\n if (raced.userId === userId) {\n return raced;\n }\n\n throw new IdentityProviderAccountAlreadyLinkedError();\n }\n\n throw new ValidationError('The user is already linked to this identity provider through another account.');\n }\n }\n\n protected pickCandidate(\n identity: IdentityProviderIdentity,\n key: keyof User,\n maxLength: number,\n ): string | null {\n const candidates = identity.attributeCandidates?.[key] || [];\n for (const candidate of candidates) {\n if (typeof candidate === 'string' && candidate.length > 0) {\n return candidate.slice(0, maxLength);\n }\n }\n\n return null;\n }\n\n async saveUser(\n identity: IdentityProviderIdentity,\n user?: User,\n ): Promise<User> {\n const attributes = await this.attributesMapper.execute(\n identity,\n );\n\n const entity : Record<string, any> = {};\n for (const attribute of attributes) {\n if (\n attribute.key &&\n attribute.operation === IdentityProviderMapperOperation.CREATE\n ) {\n // attribute value might be object, array, ...\n entity[attribute.key] = attribute.value;\n }\n }\n\n if (!user) {\n entity.realmId = identity.provider.realmId;\n entity.active = true;\n entity.nameLocked = true;\n entity.clientId = identity.clientId || null;\n }\n\n const attributesSelf = await this.validateAttributes(entity, identity, 10);\n if (!attributesSelf) {\n // todo: better error name\n throw new Error('Identity provider attributes could not be validated.');\n }\n const attributesSelfKeys = Object.keys(attributesSelf);\n\n const attributesExtra : Record<string, any> = {};\n\n const entityKeys = Object.keys(entity);\n for (const entityKey of entityKeys) {\n const index = attributesSelfKeys.indexOf(entityKey);\n if (index !== -1) {\n continue;\n }\n\n attributesExtra[entityKey] = entity[entityKey];\n }\n\n let output : User;\n if (user) {\n output = extendObject(user, attributesSelf);\n } else {\n output = attributesSelf;\n }\n\n if (typeof output.name === 'string') {\n output.name = output.name.trim().toLowerCase();\n }\n\n let attempts = Math.max((identity.attributeCandidates?.name?.length || 0) + 1, 10);\n while (attempts > 0) {\n try {\n // todo: we also need to remove existing ones via idp login flow ( but not other attributes!)\n return await this.userRepository.saveOneWithEA(output, attributesExtra);\n } catch {\n const names = identity.attributeCandidates?.name || [];\n if (names.length > 0) {\n while (names.length > 0) {\n output.name = `${names.shift()}`.trim().toLowerCase();\n\n try {\n await this.userValidator.run(output, {\n group: identity.operation === IdentityProviderIdentityOperation.CREATE ?\n ValidatorGroup.CREATE :\n ValidatorGroup.UPDATE,\n });\n break;\n } catch {\n // todo: do nothing.\n }\n }\n } else {\n output.name = createNanoID('0123456789abcdefghijklmnopqrstuvwxyz-_', 10);\n }\n\n if (isUserFakeEmail(output.email)) {\n output.email = buildUserFakeEmail(output.name);\n }\n\n attempts -= 1;\n }\n }\n\n throw new Error('The user account could not be created due a conflict error.');\n }\n\n async validateAttributes(\n entity: Record<string, any>,\n identity: IdentityProviderIdentity,\n attempts: number,\n ) : Promise<User | null> {\n attempts--;\n if (attempts <= 0) {\n return null;\n }\n\n try {\n return await this.userValidator.run(entity, {\n group: identity.operation === IdentityProviderIdentityOperation.CREATE ?\n ValidatorGroup.CREATE :\n ValidatorGroup.UPDATE,\n });\n } catch (e: any) {\n if (!isValidupError(e)) {\n return null;\n }\n\n let retry = false;\n for (let i = 0; i < e.issues.length; i++) {\n const child = e.issues[i];\n\n const pathNormalized = stringifyPath(child.path);\n\n if (\n Array.isArray(entity[pathNormalized]) &&\n entity[pathNormalized].length > 0\n ) {\n const [first, ...rest] = entity[pathNormalized];\n entity[pathNormalized] = first;\n\n if (rest.length > 0) {\n if (!identity.attributeCandidates) {\n identity.attributeCandidates = {};\n }\n\n if (!identity.attributeCandidates[pathNormalized]) {\n identity.attributeCandidates[pathNormalized] = [];\n }\n\n identity.attributeCandidates[pathNormalized]!.push(...rest);\n }\n\n retry = true;\n break;\n }\n\n if (\n identity.attributeCandidates &&\n identity.attributeCandidates[pathNormalized] &&\n identity.attributeCandidates[pathNormalized]!.length > 0\n ) {\n entity[pathNormalized] = identity.attributeCandidates[pathNormalized]!.shift();\n retry = true;\n break;\n }\n\n if (\n entity.name &&\n pathNormalized === 'email'\n ) {\n entity[pathNormalized] = buildUserFakeEmail(entity.name);\n retry = true;\n break;\n }\n\n if (entity[pathNormalized]) {\n entity[pathNormalized] = null;\n break;\n }\n }\n\n if (retry) {\n return this.validateAttributes(entity, identity, attempts);\n }\n\n return null;\n }\n }\n\n async savePermissions(\n identity: IdentityProviderIdentity,\n user: User,\n ) {\n const entities = await this.permissionMapper.execute(identity);\n\n await this.userRepository.savePermissions(user, entities);\n }\n\n async saveRoles(\n identity: IdentityProviderIdentity,\n user: User,\n ) {\n const entities = await this.roleMapper.execute(identity);\n\n await this.userRepository.saveRoles(user, entities);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"module.mjs","names":["UserValidator","buildUserFakeEmail","isUserFakeEmail","ValidatorGroup","createNanoID","extendObject","ValidationError","isEntityConflictError","isValidupError","stringifyPath","describeError","IdentityProviderIdentityOperation","IdentityProviderMapperOperation","IdentityProviderAccountAlreadyLinkedError","IdentityProviderAccountManager","attributesMapper","permissionMapper","roleMapper","repository","userRepository","userValidator","logger","ctx","attributeMapper","save","identity","account","findOneByProviderIdentity","update","operation","CREATE","user","saveUser","providerId","provider","id","providerUserId","providerUserName","name","providerRealmId","realmId","userId","userRealmId","e","raced","remove","removeError","warn","saveRoles","savePermissions","UPDATE","link","findOneById","pickCandidate","slice","providerUserEmail","existing","undefined","key","maxLength","candidates","attributeCandidates","candidate","length","attributes","execute","entity","attribute","value","active","nameLocked","clientId","attributesSelf","validateAttributes","Error","attributesSelfKeys","Object","keys","attributesExtra","entityKeys","entityKey","index","indexOf","output","trim","toLowerCase","attempts","Math","max","saveOneWithEA","names","shift","run","group","email","retry","i","issues","child","pathNormalized","path","Array","isArray","first","rest","push","entities"],"sources":["../../../../../src/core/identity/provider/account/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 { IdentityProviderAccount, User } from '@authup/core-kit';\nimport {\n UserValidator,\n buildUserFakeEmail,\n isUserFakeEmail,\n} from '@authup/core-kit';\nimport { ValidatorGroup, createNanoID, extendObject } from '@authup/kit';\nimport { ValidationError, isEntityConflictError } from '@authup/errors';\nimport { isValidupError, stringifyPath } from 'validup';\nimport type { Logger } from '@authup/server-kit';\nimport { describeError } from '../../../../utils/index.ts';\nimport type { IUserIdentityRepository } from '../../entities/index.ts';\nimport { IdentityProviderIdentityOperation } from '../constants.ts';\nimport type { IIdentityProviderMapper } from '../mapper/index.ts';\nimport { IdentityProviderMapperOperation } from '../mapper/index.ts';\nimport type { IdentityProviderIdentity } from '../types.ts';\nimport { IdentityProviderAccountAlreadyLinkedError } from './error.ts';\nimport type { IIdentityProviderAccountManager, IIdentityProviderAccountRepository, IdentityProviderAccountManagerContext } from './types.ts';\n\nexport class IdentityProviderAccountManager implements IIdentityProviderAccountManager {\n protected attributesMapper : IIdentityProviderMapper;\n\n protected permissionMapper : IIdentityProviderMapper;\n\n protected roleMapper : IIdentityProviderMapper;\n\n protected repository : IIdentityProviderAccountRepository;\n\n protected userRepository: IUserIdentityRepository;\n\n protected userValidator : UserValidator;\n\n protected logger?: Logger;\n\n constructor(ctx: IdentityProviderAccountManagerContext) {\n this.attributesMapper = ctx.attributeMapper;\n this.permissionMapper = ctx.permissionMapper;\n this.roleMapper = ctx.roleMapper;\n this.repository = ctx.repository;\n this.userRepository = ctx.userRepository;\n this.logger = ctx.logger;\n\n this.userValidator = new UserValidator();\n }\n\n async save(identity: IdentityProviderIdentity): Promise<IdentityProviderAccount> {\n let account = await this.repository.findOneByProviderIdentity(identity);\n if (account) {\n return this.update(identity, account);\n }\n\n identity.operation = IdentityProviderIdentityOperation.CREATE;\n\n const user = await this.saveUser(identity);\n\n try {\n account = await this.repository.save({\n providerId: identity.provider.id,\n providerUserId: identity.id,\n providerUserName: user.name, // todo: parse identity.name\n providerRealmId: identity.provider.realmId,\n user,\n userId: user.id,\n userRealmId: user.realmId,\n });\n } catch (e) {\n if (!isEntityConflictError(e)) {\n throw e;\n }\n\n // the loser of two concurrent first logins: the identity is linked\n // now, so continue with the winner's account and drop the user\n // this request provisioned moments ago (unreferenced; best effort,\n // a leftover row must not fail the login).\n const raced = await this.repository.findOneByProviderIdentity(identity);\n if (!raced) {\n throw e;\n }\n\n try {\n await this.userRepository.remove(user);\n } catch (removeError) {\n // The row is unreferenced, so it costs nothing but a squatted\n // user name. Left unreported it would be invisible forever.\n this.logger?.warn(describeError(\n removeError,\n `The user provisioned for the external identity \"${identity.id}\" could not be removed after losing a concurrent first login.`,\n ));\n }\n\n return this.update(identity, raced);\n }\n\n await this.saveRoles(identity, account.user);\n await this.savePermissions(identity, account.user);\n\n return account;\n }\n\n protected async update(\n identity: IdentityProviderIdentity,\n account: IdentityProviderAccount,\n ): Promise<IdentityProviderAccount> {\n identity.operation = IdentityProviderIdentityOperation.UPDATE;\n\n account.user = await this.saveUser(identity, account.user);\n\n await this.repository.save(account);\n\n await this.saveRoles(identity, account.user);\n await this.savePermissions(identity, account.user);\n\n return account;\n }\n\n async link(identity: IdentityProviderIdentity, userId: string): Promise<IdentityProviderAccount> {\n const user = await this.userRepository.findOneById(userId);\n if (!user) {\n throw new ValidationError('The linking user does not exist.');\n }\n\n if (\n identity.provider.realmId &&\n user.realmId !== identity.provider.realmId\n ) {\n throw new ValidationError('The provider and user realm do not match.');\n }\n\n const providerUserName = this.pickCandidate(identity, 'name', 256) ?? identity.id.slice(0, 256);\n const providerUserEmail = this.pickCandidate(identity, 'email', 512);\n\n const existing = await this.repository.findOneByProviderIdentity(identity);\n if (existing) {\n if (existing.userId !== userId) {\n throw new IdentityProviderAccountAlreadyLinkedError();\n }\n\n existing.providerUserName = providerUserName ?? existing.providerUserName;\n existing.providerUserEmail = providerUserEmail ?? existing.providerUserEmail;\n\n return this.repository.save(existing);\n }\n\n try {\n return await this.repository.save({\n providerId: identity.provider.id,\n providerUserId: identity.id,\n providerUserName,\n providerUserEmail: providerUserEmail ?? undefined,\n providerRealmId: identity.provider.realmId,\n userId,\n userRealmId: user.realmId ?? null,\n });\n } catch (e) {\n if (!isEntityConflictError(e)) {\n throw e;\n }\n\n // one of the two unique indexes fired; the re-read tells which:\n // a row for the identity means (providerUserId, providerId), a\n // race with the SAME user (two Connect tabs) being a no-op; no\n // row means (providerId, userId), the user already holds a link\n // at this provider through another external account.\n const raced = await this.repository.findOneByProviderIdentity(identity);\n if (raced) {\n if (raced.userId === userId) {\n return raced;\n }\n\n throw new IdentityProviderAccountAlreadyLinkedError();\n }\n\n throw new ValidationError('The user is already linked to this identity provider through another account.');\n }\n }\n\n protected pickCandidate(\n identity: IdentityProviderIdentity,\n key: keyof User,\n maxLength: number,\n ): string | null {\n const candidates = identity.attributeCandidates?.[key] || [];\n for (const candidate of candidates) {\n if (typeof candidate === 'string' && candidate.length > 0) {\n return candidate.slice(0, maxLength);\n }\n }\n\n return null;\n }\n\n async saveUser(\n identity: IdentityProviderIdentity,\n user?: User,\n ): Promise<User> {\n const attributes = await this.attributesMapper.execute(\n identity,\n );\n\n const entity : Record<string, any> = {};\n for (const attribute of attributes) {\n if (\n attribute.key &&\n attribute.operation === IdentityProviderMapperOperation.CREATE\n ) {\n // attribute value might be object, array, ...\n entity[attribute.key] = attribute.value;\n }\n }\n\n if (!user) {\n entity.realmId = identity.provider.realmId;\n entity.active = true;\n entity.nameLocked = true;\n entity.clientId = identity.clientId || null;\n }\n\n const attributesSelf = await this.validateAttributes(entity, identity, 10);\n if (!attributesSelf) {\n // todo: better error name\n throw new Error('Identity provider attributes could not be validated.');\n }\n const attributesSelfKeys = Object.keys(attributesSelf);\n\n const attributesExtra : Record<string, any> = {};\n\n const entityKeys = Object.keys(entity);\n for (const entityKey of entityKeys) {\n const index = attributesSelfKeys.indexOf(entityKey);\n if (index !== -1) {\n continue;\n }\n\n attributesExtra[entityKey] = entity[entityKey];\n }\n\n let output : User;\n if (user) {\n output = extendObject(user, attributesSelf);\n } else {\n output = attributesSelf;\n }\n\n if (typeof output.name === 'string') {\n output.name = output.name.trim().toLowerCase();\n }\n\n let attempts = Math.max((identity.attributeCandidates?.name?.length || 0) + 1, 10);\n while (attempts > 0) {\n try {\n // todo: we also need to remove existing ones via idp login flow ( but not other attributes!)\n return await this.userRepository.saveOneWithEA(output, attributesExtra);\n } catch {\n const names = identity.attributeCandidates?.name || [];\n if (names.length > 0) {\n while (names.length > 0) {\n output.name = `${names.shift()}`.trim().toLowerCase();\n\n try {\n await this.userValidator.run(output, {\n group: identity.operation === IdentityProviderIdentityOperation.CREATE ?\n ValidatorGroup.CREATE :\n ValidatorGroup.UPDATE,\n });\n break;\n } catch {\n // todo: do nothing.\n }\n }\n } else {\n output.name = createNanoID('0123456789abcdefghijklmnopqrstuvwxyz-_', 10);\n }\n\n if (isUserFakeEmail(output.email)) {\n output.email = buildUserFakeEmail(output.name);\n }\n\n attempts -= 1;\n }\n }\n\n throw new Error('The user account could not be created due a conflict error.');\n }\n\n async validateAttributes(\n entity: Record<string, any>,\n identity: IdentityProviderIdentity,\n attempts: number,\n ) : Promise<User | null> {\n attempts--;\n if (attempts <= 0) {\n return null;\n }\n\n try {\n return await this.userValidator.run(entity, {\n group: identity.operation === IdentityProviderIdentityOperation.CREATE ?\n ValidatorGroup.CREATE :\n ValidatorGroup.UPDATE,\n });\n } catch (e: any) {\n if (!isValidupError(e)) {\n return null;\n }\n\n let retry = false;\n for (let i = 0; i < e.issues.length; i++) {\n const child = e.issues[i];\n\n const pathNormalized = stringifyPath(child.path);\n\n if (\n Array.isArray(entity[pathNormalized]) &&\n entity[pathNormalized].length > 0\n ) {\n const [first, ...rest] = entity[pathNormalized];\n entity[pathNormalized] = first;\n\n if (rest.length > 0) {\n if (!identity.attributeCandidates) {\n identity.attributeCandidates = {};\n }\n\n if (!identity.attributeCandidates[pathNormalized]) {\n identity.attributeCandidates[pathNormalized] = [];\n }\n\n identity.attributeCandidates[pathNormalized]!.push(...rest);\n }\n\n retry = true;\n break;\n }\n\n if (\n identity.attributeCandidates &&\n identity.attributeCandidates[pathNormalized] &&\n identity.attributeCandidates[pathNormalized]!.length > 0\n ) {\n entity[pathNormalized] = identity.attributeCandidates[pathNormalized]!.shift();\n retry = true;\n break;\n }\n\n if (\n pathNormalized === 'email' &&\n entity.name\n ) {\n entity[pathNormalized] = buildUserFakeEmail(entity.name);\n retry = true;\n break;\n }\n\n if (entity[pathNormalized]) {\n entity[pathNormalized] = null;\n break;\n }\n }\n\n if (retry) {\n return this.validateAttributes(entity, identity, attempts);\n }\n\n return null;\n }\n }\n\n async savePermissions(\n identity: IdentityProviderIdentity,\n user: User,\n ) {\n const entities = await this.permissionMapper.execute(identity);\n\n await this.userRepository.savePermissions(user, entities);\n }\n\n async saveRoles(\n identity: IdentityProviderIdentity,\n user: User,\n ) {\n const entities = await this.roleMapper.execute(identity);\n\n await this.userRepository.saveRoles(user, entities);\n }\n}\n"],"mappings":"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"}
@@ -3,6 +3,7 @@ import "node:url";
3
3
  import.meta.url;
4
4
  import { IdentityProviderLdapAuthenticator } from "./protocols/ldap/module.mjs";
5
5
  import { IdentityProviderLdapCollectionAuthenticator } from "./protocols/ldap/collection.mjs";
6
+ import { IDENTITY_PROVIDER_ASSURANCE_ERROR_INSTANCE, IdentityProviderAssuranceError, assertIdentityProviderAssurance, buildIdentityProviderAcrValues, isIdentityProviderAssuranceError } from "./protocols/oauth2/assurance.mjs";
6
7
  import { IdentityProviderOAuth2Authenticator } from "./protocols/oauth2/module.mjs";
7
8
  import { IdentityProviderOpenIDAuthenticator } from "./protocols/open-id/module.mjs";
8
9
  import "./protocols/index.mjs";
@@ -14,4 +15,4 @@ import { IdentityProviderPaypalAuthenticator } from "./presets/paypal.mjs";
14
15
  import "./presets/index.mjs";
15
16
  import { createIdentityProviderOAuth2Authenticator } from "./factory.mjs";
16
17
  import { IDENTITY_PROVIDER_LDAP_COLLECTION_AUTHENTICATOR_TOKEN } from "./constants.mjs";
17
- export { IDENTITY_PROVIDER_LDAP_COLLECTION_AUTHENTICATOR_TOKEN, IdentityProviderFacebookAuthenticator, IdentityProviderGithubAuthenticator, IdentityProviderGoogleAuthenticator, IdentityProviderInstagramAuthenticator, IdentityProviderLdapAuthenticator, IdentityProviderLdapCollectionAuthenticator, IdentityProviderOAuth2Authenticator, IdentityProviderOpenIDAuthenticator, IdentityProviderPaypalAuthenticator, createIdentityProviderOAuth2Authenticator };
18
+ export { IDENTITY_PROVIDER_ASSURANCE_ERROR_INSTANCE, IDENTITY_PROVIDER_LDAP_COLLECTION_AUTHENTICATOR_TOKEN, IdentityProviderAssuranceError, IdentityProviderFacebookAuthenticator, IdentityProviderGithubAuthenticator, IdentityProviderGoogleAuthenticator, IdentityProviderInstagramAuthenticator, IdentityProviderLdapAuthenticator, IdentityProviderLdapCollectionAuthenticator, IdentityProviderOAuth2Authenticator, IdentityProviderOpenIDAuthenticator, IdentityProviderPaypalAuthenticator, assertIdentityProviderAssurance, buildIdentityProviderAcrValues, createIdentityProviderOAuth2Authenticator, isIdentityProviderAssuranceError };
@@ -4,8 +4,9 @@ import.meta.url;
4
4
  import { IdentityProviderLdapAuthenticator } from "./ldap/module.mjs";
5
5
  import { IdentityProviderLdapCollectionAuthenticator } from "./ldap/collection.mjs";
6
6
  import "./ldap/index.mjs";
7
+ import { IDENTITY_PROVIDER_ASSURANCE_ERROR_INSTANCE, IdentityProviderAssuranceError, assertIdentityProviderAssurance, buildIdentityProviderAcrValues, isIdentityProviderAssuranceError } from "./oauth2/assurance.mjs";
7
8
  import { IdentityProviderOAuth2Authenticator } from "./oauth2/module.mjs";
8
9
  import "./oauth2/index.mjs";
9
10
  import { IdentityProviderOpenIDAuthenticator } from "./open-id/module.mjs";
10
11
  import "./open-id/index.mjs";
11
- export { IdentityProviderLdapAuthenticator, IdentityProviderLdapCollectionAuthenticator, IdentityProviderOAuth2Authenticator, IdentityProviderOpenIDAuthenticator };
12
+ export { IDENTITY_PROVIDER_ASSURANCE_ERROR_INSTANCE, IdentityProviderAssuranceError, IdentityProviderLdapAuthenticator, IdentityProviderLdapCollectionAuthenticator, IdentityProviderOAuth2Authenticator, IdentityProviderOpenIDAuthenticator, assertIdentityProviderAssurance, buildIdentityProviderAcrValues, isIdentityProviderAssuranceError };
@@ -0,0 +1,46 @@
1
+ import type { OAuth2IdentityProviderBase } from '@authup/core-kit';
2
+ import { ValidationError } from '@authup/errors';
3
+ export declare const IDENTITY_PROVIDER_ASSURANCE_ERROR_INSTANCE: unique symbol;
4
+ /**
5
+ * The upstream did not meet the provider's `requiredAmr` / `requiredAcr`.
6
+ *
7
+ * It adds no dedicated `ErrorCode` and keeps `ValidationError`'s shared
8
+ * `BAD_REQUEST`, so the marker is the ONLY thing the guard may read - a
9
+ * code fallback would match every other `ValidationError` in the process.
10
+ * That is sound here because both callers swallow it into a redirect (the
11
+ * login bounces to the hosted page with `access_denied`, the link callback
12
+ * with `linkError`), so it never crosses a wire boundary. The reason lands
13
+ * in the operator's log instead, which is where a misconfigured allow-list
14
+ * is debugged.
15
+ */
16
+ export declare class IdentityProviderAssuranceError extends ValidationError {
17
+ constructor(message: string);
18
+ }
19
+ export declare function isIdentityProviderAssuranceError(input: unknown): input is IdentityProviderAssuranceError;
20
+ /**
21
+ * The `acr_values` an outbound authorize request asks for, so the upstream is
22
+ * asked to step up rather than merely observed. Voluntary in OIDC Core
23
+ * 5.5.1.1 - a provider may ignore it and answer anyway, which is exactly what
24
+ * {@see assertIdentityProviderAssurance} is for.
25
+ */
26
+ export declare function buildIdentityProviderAcrValues(provider: Partial<OAuth2IdentityProviderBase>): string | undefined;
27
+ /**
28
+ * Verify what the upstream actually returned against the provider's
29
+ * allow-lists.
30
+ *
31
+ * Fail closed on every uncertainty: the claims are read from the `id_token`
32
+ * alone, so a provider that returns none - or one whose token carries neither
33
+ * claim, or cannot be decoded - is refused once an allow-list is set. Failing
34
+ * open there would make the feature decorative.
35
+ *
36
+ * The token is DECODED, not verified, and that is not an oversight. It is the
37
+ * return value of the server's own back-channel POST to the operator-configured
38
+ * `tokenUrl`, so OIDC Core 3.1.3.7 item 6 accepts TLS server validation in
39
+ * place of checking the signature. No browser-supplied token reaches here, and
40
+ * a provider the operator configured is the authentication authority for these
41
+ * users anyway: one that lies about `amr` could equally mint any subject. What
42
+ * item 6 does NOT waive is the audience, which is checked below because
43
+ * `clientId` is already in hand.
44
+ */
45
+ export declare function assertIdentityProviderAssurance(provider: Partial<OAuth2IdentityProviderBase>, idToken?: string): void;
46
+ //# sourceMappingURL=assurance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assurance.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/identity/provider/authentication/protocols/oauth2/assurance.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAqC,MAAM,gBAAgB,CAAC;AAGpF,eAAO,MAAM,0CAA0C,eAAmE,CAAC;AAE3H;;;;;;;;;;;GAWG;AACH,qBAAa,8BAA+B,SAAQ,eAAe;gBACnD,OAAO,EAAE,MAAM;CAI9B;AAED,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,8BAA8B,CAExG;AAiBD;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,OAAO,CAAC,0BAA0B,CAAC,GAAG,MAAM,GAAG,SAAS,CAGhH;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,+BAA+B,CAC3C,QAAQ,EAAE,OAAO,CAAC,0BAA0B,CAAC,EAC7C,OAAO,CAAC,EAAE,MAAM,GACjB,IAAI,CAgEN"}