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

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 (410) hide show
  1. package/dist/adapters/database/domains/role/entity.d.ts.map +1 -1
  2. package/dist/adapters/database/domains/role/entity.mjs +2 -1
  3. package/dist/adapters/database/domains/role/entity.mjs.map +1 -1
  4. package/dist/adapters/database/migrations/mysql/1784970000000-RoleClientForeignKey.d.ts +25 -0
  5. package/dist/adapters/database/migrations/mysql/1784970000000-RoleClientForeignKey.d.ts.map +1 -0
  6. package/dist/adapters/database/migrations/mysql/1784970000000-RoleClientForeignKey.mjs +60 -0
  7. package/dist/adapters/database/migrations/mysql/1784970000000-RoleClientForeignKey.mjs.map +1 -0
  8. package/dist/adapters/database/migrations/postgres/1784970000000-RoleClientForeignKey.d.ts +25 -0
  9. package/dist/adapters/database/migrations/postgres/1784970000000-RoleClientForeignKey.d.ts.map +1 -0
  10. package/dist/adapters/database/migrations/postgres/1784970000000-RoleClientForeignKey.mjs +60 -0
  11. package/dist/adapters/database/migrations/postgres/1784970000000-RoleClientForeignKey.mjs.map +1 -0
  12. package/dist/adapters/http/adapters/oauth2/grant-types/authorize.mjs +1 -1
  13. package/dist/adapters/http/adapters/oauth2/grant-types/authorize.mjs.map +1 -1
  14. package/dist/adapters/http/adapters/oauth2/grant-types/client-credentials.mjs +1 -1
  15. package/dist/adapters/http/adapters/oauth2/grant-types/client-credentials.mjs.map +1 -1
  16. package/dist/adapters/http/adapters/oauth2/grant-types/identity.mjs +1 -1
  17. package/dist/adapters/http/adapters/oauth2/grant-types/identity.mjs.map +1 -1
  18. package/dist/adapters/http/adapters/oauth2/grant-types/password.mjs +1 -1
  19. package/dist/adapters/http/adapters/oauth2/grant-types/password.mjs.map +1 -1
  20. package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.mjs +1 -1
  21. package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.mjs.map +1 -1
  22. package/dist/adapters/http/controllers/entities/client/module.d.ts +6 -6
  23. package/dist/adapters/http/controllers/entities/client/module.d.ts.map +1 -1
  24. package/dist/adapters/http/controllers/entities/client/module.mjs +30 -7
  25. package/dist/adapters/http/controllers/entities/client/module.mjs.map +1 -1
  26. package/dist/adapters/http/controllers/entities/client-permission/module.d.ts +5 -5
  27. package/dist/adapters/http/controllers/entities/client-permission/module.d.ts.map +1 -1
  28. package/dist/adapters/http/controllers/entities/client-permission/module.mjs +23 -5
  29. package/dist/adapters/http/controllers/entities/client-permission/module.mjs.map +1 -1
  30. package/dist/adapters/http/controllers/entities/client-role/module.d.ts +4 -4
  31. package/dist/adapters/http/controllers/entities/client-role/module.d.ts.map +1 -1
  32. package/dist/adapters/http/controllers/entities/client-role/module.mjs +19 -4
  33. package/dist/adapters/http/controllers/entities/client-role/module.mjs.map +1 -1
  34. package/dist/adapters/http/controllers/entities/client-scope/module.d.ts +4 -4
  35. package/dist/adapters/http/controllers/entities/client-scope/module.d.ts.map +1 -1
  36. package/dist/adapters/http/controllers/entities/client-scope/module.mjs +19 -4
  37. package/dist/adapters/http/controllers/entities/client-scope/module.mjs.map +1 -1
  38. package/dist/adapters/http/controllers/entities/consent/module.d.ts +3 -3
  39. package/dist/adapters/http/controllers/entities/consent/module.d.ts.map +1 -1
  40. package/dist/adapters/http/controllers/entities/consent/module.mjs +15 -3
  41. package/dist/adapters/http/controllers/entities/consent/module.mjs.map +1 -1
  42. package/dist/adapters/http/controllers/entities/event/module.d.ts +2 -2
  43. package/dist/adapters/http/controllers/entities/event/module.d.ts.map +1 -1
  44. package/dist/adapters/http/controllers/entities/event/module.mjs +11 -2
  45. package/dist/adapters/http/controllers/entities/event/module.mjs.map +1 -1
  46. package/dist/adapters/http/controllers/entities/identity-provide-role/module.d.ts +5 -5
  47. package/dist/adapters/http/controllers/entities/identity-provide-role/module.d.ts.map +1 -1
  48. package/dist/adapters/http/controllers/entities/identity-provide-role/module.mjs +23 -5
  49. package/dist/adapters/http/controllers/entities/identity-provide-role/module.mjs.map +1 -1
  50. package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts +6 -6
  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 +23 -7
  53. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs.map +1 -1
  54. package/dist/adapters/http/controllers/entities/key/module.d.ts +5 -5
  55. package/dist/adapters/http/controllers/entities/key/module.d.ts.map +1 -1
  56. package/dist/adapters/http/controllers/entities/key/module.mjs +23 -5
  57. package/dist/adapters/http/controllers/entities/key/module.mjs.map +1 -1
  58. package/dist/adapters/http/controllers/entities/permission/module.d.ts +6 -6
  59. package/dist/adapters/http/controllers/entities/permission/module.d.ts.map +1 -1
  60. package/dist/adapters/http/controllers/entities/permission/module.mjs +27 -6
  61. package/dist/adapters/http/controllers/entities/permission/module.mjs.map +1 -1
  62. package/dist/adapters/http/controllers/entities/permission-policy/module.d.ts +4 -4
  63. package/dist/adapters/http/controllers/entities/permission-policy/module.d.ts.map +1 -1
  64. package/dist/adapters/http/controllers/entities/permission-policy/module.mjs +19 -4
  65. package/dist/adapters/http/controllers/entities/permission-policy/module.mjs.map +1 -1
  66. package/dist/adapters/http/controllers/entities/policy/module.d.ts +7 -7
  67. package/dist/adapters/http/controllers/entities/policy/module.d.ts.map +1 -1
  68. package/dist/adapters/http/controllers/entities/policy/module.mjs +27 -6
  69. package/dist/adapters/http/controllers/entities/policy/module.mjs.map +1 -1
  70. package/dist/adapters/http/controllers/entities/realm/module.d.ts +6 -6
  71. package/dist/adapters/http/controllers/entities/realm/module.d.ts.map +1 -1
  72. package/dist/adapters/http/controllers/entities/realm/module.mjs +29 -8
  73. package/dist/adapters/http/controllers/entities/realm/module.mjs.map +1 -1
  74. package/dist/adapters/http/controllers/entities/role/module.d.ts +6 -6
  75. package/dist/adapters/http/controllers/entities/role/module.d.ts.map +1 -1
  76. package/dist/adapters/http/controllers/entities/role/module.mjs +27 -6
  77. package/dist/adapters/http/controllers/entities/role/module.mjs.map +1 -1
  78. package/dist/adapters/http/controllers/entities/role-attribute/module.d.ts +5 -5
  79. package/dist/adapters/http/controllers/entities/role-attribute/module.d.ts.map +1 -1
  80. package/dist/adapters/http/controllers/entities/role-attribute/module.mjs +23 -5
  81. package/dist/adapters/http/controllers/entities/role-attribute/module.mjs.map +1 -1
  82. package/dist/adapters/http/controllers/entities/role-permission/module.d.ts +5 -5
  83. package/dist/adapters/http/controllers/entities/role-permission/module.d.ts.map +1 -1
  84. package/dist/adapters/http/controllers/entities/role-permission/module.mjs +23 -5
  85. package/dist/adapters/http/controllers/entities/role-permission/module.mjs.map +1 -1
  86. package/dist/adapters/http/controllers/entities/scope/module.d.ts +6 -6
  87. package/dist/adapters/http/controllers/entities/scope/module.d.ts.map +1 -1
  88. package/dist/adapters/http/controllers/entities/scope/module.mjs +27 -6
  89. package/dist/adapters/http/controllers/entities/scope/module.mjs.map +1 -1
  90. package/dist/adapters/http/controllers/entities/session/module.d.ts +3 -3
  91. package/dist/adapters/http/controllers/entities/session/module.d.ts.map +1 -1
  92. package/dist/adapters/http/controllers/entities/session/module.mjs +15 -3
  93. package/dist/adapters/http/controllers/entities/session/module.mjs.map +1 -1
  94. package/dist/adapters/http/controllers/entities/trust-anchor/module.d.ts +5 -5
  95. package/dist/adapters/http/controllers/entities/trust-anchor/module.d.ts.map +1 -1
  96. package/dist/adapters/http/controllers/entities/trust-anchor/module.mjs +23 -5
  97. package/dist/adapters/http/controllers/entities/trust-anchor/module.mjs.map +1 -1
  98. package/dist/adapters/http/controllers/entities/user/module.d.ts +6 -6
  99. package/dist/adapters/http/controllers/entities/user/module.d.ts.map +1 -1
  100. package/dist/adapters/http/controllers/entities/user/module.mjs +27 -6
  101. package/dist/adapters/http/controllers/entities/user/module.mjs.map +1 -1
  102. package/dist/adapters/http/controllers/entities/user-attribute/module.d.ts +5 -5
  103. package/dist/adapters/http/controllers/entities/user-attribute/module.d.ts.map +1 -1
  104. package/dist/adapters/http/controllers/entities/user-attribute/module.mjs +23 -5
  105. package/dist/adapters/http/controllers/entities/user-attribute/module.mjs.map +1 -1
  106. package/dist/adapters/http/controllers/entities/user-authenticator/module.d.ts +4 -4
  107. package/dist/adapters/http/controllers/entities/user-authenticator/module.d.ts.map +1 -1
  108. package/dist/adapters/http/controllers/entities/user-authenticator/module.mjs +19 -4
  109. package/dist/adapters/http/controllers/entities/user-authenticator/module.mjs.map +1 -1
  110. package/dist/adapters/http/controllers/entities/user-permission/module.d.ts +5 -5
  111. package/dist/adapters/http/controllers/entities/user-permission/module.d.ts.map +1 -1
  112. package/dist/adapters/http/controllers/entities/user-permission/module.mjs +23 -5
  113. package/dist/adapters/http/controllers/entities/user-permission/module.mjs.map +1 -1
  114. package/dist/adapters/http/controllers/entities/user-role/module.d.ts +4 -4
  115. package/dist/adapters/http/controllers/entities/user-role/module.d.ts.map +1 -1
  116. package/dist/adapters/http/controllers/entities/user-role/module.mjs +19 -4
  117. package/dist/adapters/http/controllers/entities/user-role/module.mjs.map +1 -1
  118. package/dist/adapters/http/controllers/index.mjs +2 -1
  119. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.mjs +1 -1
  120. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.mjs.map +1 -1
  121. package/dist/adapters/http/controllers/workflows/index.d.ts +1 -0
  122. package/dist/adapters/http/controllers/workflows/index.d.ts.map +1 -1
  123. package/dist/adapters/http/controllers/workflows/index.mjs +3 -1
  124. package/dist/adapters/http/controllers/workflows/logout/module.d.ts.map +1 -1
  125. package/dist/adapters/http/controllers/workflows/logout/module.mjs +5 -1
  126. package/dist/adapters/http/controllers/workflows/logout/module.mjs.map +1 -1
  127. package/dist/adapters/http/controllers/workflows/userinfo/index.d.ts +2 -0
  128. package/dist/adapters/http/controllers/workflows/userinfo/index.d.ts.map +1 -0
  129. package/dist/adapters/http/controllers/workflows/userinfo/index.mjs +5 -0
  130. package/dist/adapters/http/controllers/workflows/userinfo/module.d.ts +18 -0
  131. package/dist/adapters/http/controllers/workflows/userinfo/module.d.ts.map +1 -0
  132. package/dist/adapters/http/controllers/workflows/userinfo/module.mjs +53 -0
  133. package/dist/adapters/http/controllers/workflows/userinfo/module.mjs.map +1 -0
  134. package/dist/adapters/http/index.mjs +2 -1
  135. package/dist/adapters/http/middleware/built-in/authorization/module.d.ts +1 -0
  136. package/dist/adapters/http/middleware/built-in/authorization/module.d.ts.map +1 -1
  137. package/dist/adapters/http/middleware/built-in/authorization/module.mjs +8 -0
  138. package/dist/adapters/http/middleware/built-in/authorization/module.mjs.map +1 -1
  139. package/dist/adapters/http/middleware/built-in/rate-limit.d.ts.map +1 -1
  140. package/dist/adapters/http/middleware/built-in/rate-limit.mjs +2 -0
  141. package/dist/adapters/http/middleware/built-in/rate-limit.mjs.map +1 -1
  142. package/dist/adapters/http/request/event-context.mjs +1 -1
  143. package/dist/adapters/http/request/event-context.mjs.map +1 -1
  144. package/dist/app/factory.d.ts +2 -1
  145. package/dist/app/factory.d.ts.map +1 -1
  146. package/dist/app/factory.mjs +2 -2
  147. package/dist/app/factory.mjs.map +1 -1
  148. package/dist/app/index.d.ts +1 -0
  149. package/dist/app/index.d.ts.map +1 -1
  150. package/dist/app/index.mjs +5 -1
  151. package/dist/app/modules/authentication/repositories/session.mjs +2 -2
  152. package/dist/app/modules/authentication/repositories/session.mjs.map +1 -1
  153. package/dist/app/modules/components/module.d.ts +3 -0
  154. package/dist/app/modules/components/module.d.ts.map +1 -1
  155. package/dist/app/modules/components/module.mjs +17 -2
  156. package/dist/app/modules/components/module.mjs.map +1 -1
  157. package/dist/app/modules/config/constants.d.ts +1 -0
  158. package/dist/app/modules/config/constants.d.ts.map +1 -1
  159. package/dist/app/modules/config/constants.mjs +1 -0
  160. package/dist/app/modules/config/constants.mjs.map +1 -1
  161. package/dist/app/modules/config/helpers.d.ts +9 -0
  162. package/dist/app/modules/config/helpers.d.ts.map +1 -0
  163. package/dist/app/modules/config/helpers.mjs +21 -0
  164. package/dist/app/modules/config/helpers.mjs.map +1 -0
  165. package/dist/app/modules/config/index.d.ts +2 -0
  166. package/dist/app/modules/config/index.d.ts.map +1 -1
  167. package/dist/app/modules/config/index.mjs +6 -1
  168. package/dist/app/modules/config/module.d.ts.map +1 -1
  169. package/dist/app/modules/config/module.mjs +2 -7
  170. package/dist/app/modules/config/module.mjs.map +1 -1
  171. package/dist/app/modules/config/normalize.d.ts.map +1 -1
  172. package/dist/app/modules/config/normalize.mjs +4 -0
  173. package/dist/app/modules/config/normalize.mjs.map +1 -1
  174. package/dist/app/modules/config/read/env.d.ts.map +1 -1
  175. package/dist/app/modules/config/read/env.mjs +2 -0
  176. package/dist/app/modules/config/read/env.mjs.map +1 -1
  177. package/dist/app/modules/config/read/fs.d.ts.map +1 -1
  178. package/dist/app/modules/config/read/fs.mjs +31 -8
  179. package/dist/app/modules/config/read/fs.mjs.map +1 -1
  180. package/dist/app/modules/config/trust-proxy.d.ts +28 -0
  181. package/dist/app/modules/config/trust-proxy.d.ts.map +1 -0
  182. package/dist/app/modules/config/trust-proxy.mjs +64 -0
  183. package/dist/app/modules/config/trust-proxy.mjs.map +1 -0
  184. package/dist/app/modules/config/types.d.ts +18 -0
  185. package/dist/app/modules/config/types.d.ts.map +1 -1
  186. package/dist/app/modules/config/validator.d.ts.map +1 -1
  187. package/dist/app/modules/config/validator.mjs +7 -0
  188. package/dist/app/modules/config/validator.mjs.map +1 -1
  189. package/dist/app/modules/database/repositories/client/repository.d.ts.map +1 -1
  190. package/dist/app/modules/database/repositories/client/repository.mjs +3 -4
  191. package/dist/app/modules/database/repositories/client/repository.mjs.map +1 -1
  192. package/dist/app/modules/database/repositories/client-permission/repository.mjs +2 -2
  193. package/dist/app/modules/database/repositories/client-permission/repository.mjs.map +1 -1
  194. package/dist/app/modules/database/repositories/client-role/repository.mjs +2 -2
  195. package/dist/app/modules/database/repositories/client-role/repository.mjs.map +1 -1
  196. package/dist/app/modules/database/repositories/client-scope/repository.mjs +2 -2
  197. package/dist/app/modules/database/repositories/client-scope/repository.mjs.map +1 -1
  198. package/dist/app/modules/database/repositories/event/repository.d.ts.map +1 -1
  199. package/dist/app/modules/database/repositories/event/repository.mjs +4 -3
  200. package/dist/app/modules/database/repositories/event/repository.mjs.map +1 -1
  201. package/dist/app/modules/database/repositories/identity-provider/repository.mjs +2 -2
  202. package/dist/app/modules/database/repositories/identity-provider/repository.mjs.map +1 -1
  203. package/dist/app/modules/database/repositories/identity-provider-role-mapping/repository.mjs +2 -2
  204. package/dist/app/modules/database/repositories/identity-provider-role-mapping/repository.mjs.map +1 -1
  205. package/dist/app/modules/database/repositories/key/repository.mjs +2 -2
  206. package/dist/app/modules/database/repositories/key/repository.mjs.map +1 -1
  207. package/dist/app/modules/database/repositories/permission/repository.mjs +2 -2
  208. package/dist/app/modules/database/repositories/permission/repository.mjs.map +1 -1
  209. package/dist/app/modules/database/repositories/permission-policy/repository.mjs +2 -2
  210. package/dist/app/modules/database/repositories/permission-policy/repository.mjs.map +1 -1
  211. package/dist/app/modules/database/repositories/policy/repository.mjs +2 -2
  212. package/dist/app/modules/database/repositories/policy/repository.mjs.map +1 -1
  213. package/dist/app/modules/database/repositories/query.d.ts +20 -0
  214. package/dist/app/modules/database/repositories/query.d.ts.map +1 -1
  215. package/dist/app/modules/database/repositories/query.mjs +26 -3
  216. package/dist/app/modules/database/repositories/query.mjs.map +1 -1
  217. package/dist/app/modules/database/repositories/realm/repository.mjs +2 -2
  218. package/dist/app/modules/database/repositories/realm/repository.mjs.map +1 -1
  219. package/dist/app/modules/database/repositories/role/repository.mjs +2 -2
  220. package/dist/app/modules/database/repositories/role/repository.mjs.map +1 -1
  221. package/dist/app/modules/database/repositories/role-attribute/repository.mjs +2 -2
  222. package/dist/app/modules/database/repositories/role-attribute/repository.mjs.map +1 -1
  223. package/dist/app/modules/database/repositories/role-permission/repository.mjs +2 -2
  224. package/dist/app/modules/database/repositories/role-permission/repository.mjs.map +1 -1
  225. package/dist/app/modules/database/repositories/schema-validation.d.ts +17 -3
  226. package/dist/app/modules/database/repositories/schema-validation.d.ts.map +1 -1
  227. package/dist/app/modules/database/repositories/schema-validation.mjs +29 -5
  228. package/dist/app/modules/database/repositories/schema-validation.mjs.map +1 -1
  229. package/dist/app/modules/database/repositories/scope/repository.mjs +2 -2
  230. package/dist/app/modules/database/repositories/scope/repository.mjs.map +1 -1
  231. package/dist/app/modules/database/repositories/trust-anchor/repository.mjs +2 -2
  232. package/dist/app/modules/database/repositories/trust-anchor/repository.mjs.map +1 -1
  233. package/dist/app/modules/database/repositories/user/repository.mjs +2 -2
  234. package/dist/app/modules/database/repositories/user/repository.mjs.map +1 -1
  235. package/dist/app/modules/database/repositories/user-attribute/repository.mjs +2 -2
  236. package/dist/app/modules/database/repositories/user-attribute/repository.mjs.map +1 -1
  237. package/dist/app/modules/database/repositories/user-authenticator/repository.mjs +2 -2
  238. package/dist/app/modules/database/repositories/user-authenticator/repository.mjs.map +1 -1
  239. package/dist/app/modules/database/repositories/user-permission/repository.mjs +2 -2
  240. package/dist/app/modules/database/repositories/user-permission/repository.mjs.map +1 -1
  241. package/dist/app/modules/database/repositories/user-role/repository.mjs +2 -2
  242. package/dist/app/modules/database/repositories/user-role/repository.mjs.map +1 -1
  243. package/dist/app/modules/http/constants.d.ts +2 -13
  244. package/dist/app/modules/http/constants.d.ts.map +1 -1
  245. package/dist/app/modules/http/constants.mjs.map +1 -1
  246. package/dist/app/modules/http/module.d.ts.map +1 -1
  247. package/dist/app/modules/http/module.mjs +7 -1
  248. package/dist/app/modules/http/module.mjs.map +1 -1
  249. package/dist/app/modules/http/modules/controller.d.ts +4 -2
  250. package/dist/app/modules/http/modules/controller.d.ts.map +1 -1
  251. package/dist/app/modules/http/modules/controller.mjs +16 -3
  252. package/dist/app/modules/http/modules/controller.mjs.map +1 -1
  253. package/dist/app/modules/index.mjs +5 -1
  254. package/dist/app/modules/oauth2/repositories/consent/repository.mjs +2 -2
  255. package/dist/app/modules/oauth2/repositories/consent/repository.mjs.map +1 -1
  256. package/dist/app/modules/provisioning/module.d.ts.map +1 -1
  257. package/dist/app/modules/provisioning/module.mjs +12 -4
  258. package/dist/app/modules/provisioning/module.mjs.map +1 -1
  259. package/dist/app/types.d.ts +5 -0
  260. package/dist/app/types.d.ts.map +1 -0
  261. package/dist/app/types.mjs +4 -0
  262. package/dist/cli/commands/healthcheck.d.ts +2 -1
  263. package/dist/cli/commands/healthcheck.d.ts.map +1 -1
  264. package/dist/cli/commands/healthcheck.mjs +3 -2
  265. package/dist/cli/commands/healthcheck.mjs.map +1 -1
  266. package/dist/cli/commands/index.d.ts +0 -1
  267. package/dist/cli/commands/index.d.ts.map +1 -1
  268. package/dist/cli/commands/index.mjs +1 -2
  269. package/dist/cli/commands/migration.d.ts +2 -1
  270. package/dist/cli/commands/migration.d.ts.map +1 -1
  271. package/dist/cli/commands/migration.mjs +3 -2
  272. package/dist/cli/commands/migration.mjs.map +1 -1
  273. package/dist/cli/commands/start.d.ts +2 -1
  274. package/dist/cli/commands/start.d.ts.map +1 -1
  275. package/dist/cli/commands/start.mjs +3 -2
  276. package/dist/cli/commands/start.mjs.map +1 -1
  277. package/dist/cli/config.d.ts +18 -0
  278. package/dist/cli/config.d.ts.map +1 -0
  279. package/dist/cli/config.mjs +34 -0
  280. package/dist/cli/config.mjs.map +1 -0
  281. package/dist/cli/module.d.ts +8 -8
  282. package/dist/cli/module.d.ts.map +1 -1
  283. package/dist/cli/module.mjs +8 -28
  284. package/dist/cli/module.mjs.map +1 -1
  285. package/dist/cli/types.d.ts +5 -0
  286. package/dist/cli/types.d.ts.map +1 -0
  287. package/dist/cli/types.mjs +4 -0
  288. package/dist/components/event-cleaner/module.d.ts.map +1 -1
  289. package/dist/components/event-cleaner/module.mjs +26 -14
  290. package/dist/components/event-cleaner/module.mjs.map +1 -1
  291. package/dist/components/index.d.ts +0 -1
  292. package/dist/components/index.d.ts.map +1 -1
  293. package/dist/components/index.mjs +1 -4
  294. package/dist/components/oauth2-cleaner/module.d.ts.map +1 -1
  295. package/dist/components/oauth2-cleaner/module.mjs +29 -17
  296. package/dist/components/oauth2-cleaner/module.mjs.map +1 -1
  297. package/dist/components/types.d.ts +1 -0
  298. package/dist/components/types.d.ts.map +1 -1
  299. package/dist/core/authentication/login-throttle/service.d.ts.map +1 -1
  300. package/dist/core/authentication/login-throttle/service.mjs +2 -1
  301. package/dist/core/authentication/login-throttle/service.mjs.map +1 -1
  302. package/dist/core/entities/client/constants.d.ts +10 -0
  303. package/dist/core/entities/client/constants.d.ts.map +1 -0
  304. package/dist/core/entities/client/constants.mjs +20 -0
  305. package/dist/core/entities/client/constants.mjs.map +1 -0
  306. package/dist/core/entities/client/index.d.ts +1 -0
  307. package/dist/core/entities/client/index.d.ts.map +1 -1
  308. package/dist/core/entities/client/index.mjs +3 -2
  309. package/dist/core/entities/client/schema.d.ts.map +1 -1
  310. package/dist/core/entities/client/schema.mjs +40 -3
  311. package/dist/core/entities/client/schema.mjs.map +1 -1
  312. package/dist/core/entities/client/service.d.ts.map +1 -1
  313. package/dist/core/entities/client/service.mjs +8 -60
  314. package/dist/core/entities/client/service.mjs.map +1 -1
  315. package/dist/core/entities/client/web-client.d.ts +39 -3
  316. package/dist/core/entities/client/web-client.d.ts.map +1 -1
  317. package/dist/core/entities/client/web-client.mjs +68 -12
  318. package/dist/core/entities/client/web-client.mjs.map +1 -1
  319. package/dist/core/entities/client-scope/schema.d.ts.map +1 -1
  320. package/dist/core/entities/client-scope/schema.mjs +3 -1
  321. package/dist/core/entities/client-scope/schema.mjs.map +1 -1
  322. package/dist/core/entities/event/constants.d.ts +7 -0
  323. package/dist/core/entities/event/constants.d.ts.map +1 -1
  324. package/dist/core/entities/event/constants.mjs +7 -1
  325. package/dist/core/entities/event/constants.mjs.map +1 -1
  326. package/dist/core/entities/event/index.mjs +2 -2
  327. package/dist/core/entities/event/service.mjs +1 -1
  328. package/dist/core/entities/event/service.mjs.map +1 -1
  329. package/dist/core/entities/index.mjs +4 -3
  330. package/dist/core/entities/role/schema.d.ts.map +1 -1
  331. package/dist/core/entities/role/schema.mjs +4 -0
  332. package/dist/core/entities/role/schema.mjs.map +1 -1
  333. package/dist/core/entities/session/schema.d.ts.map +1 -1
  334. package/dist/core/entities/session/schema.mjs +2 -0
  335. package/dist/core/entities/session/schema.mjs.map +1 -1
  336. package/dist/core/entities/user/schema.d.ts.map +1 -1
  337. package/dist/core/entities/user/schema.mjs +2 -0
  338. package/dist/core/entities/user/schema.mjs.map +1 -1
  339. package/dist/core/identity/password-recovery/check.mjs +4 -4
  340. package/dist/core/identity/password-recovery/check.mjs.map +1 -1
  341. package/dist/core/identity/registration/check.mjs +2 -2
  342. package/dist/core/identity/registration/check.mjs.map +1 -1
  343. package/dist/core/index.mjs +5 -3
  344. package/dist/core/key/check.mjs +2 -2
  345. package/dist/core/key/check.mjs.map +1 -1
  346. package/dist/core/provisioning/entities/client/relations-validator.d.ts.map +1 -1
  347. package/dist/core/provisioning/entities/client/relations-validator.mjs +2 -0
  348. package/dist/core/provisioning/entities/client/relations-validator.mjs.map +1 -1
  349. package/dist/core/provisioning/entities/client/types.d.ts +8 -0
  350. package/dist/core/provisioning/entities/client/types.d.ts.map +1 -1
  351. package/dist/core/provisioning/synchronizer/client/module.d.ts +3 -1
  352. package/dist/core/provisioning/synchronizer/client/module.d.ts.map +1 -1
  353. package/dist/core/provisioning/synchronizer/client/module.mjs +10 -0
  354. package/dist/core/provisioning/synchronizer/client/module.mjs.map +1 -1
  355. package/dist/core/provisioning/synchronizer/client/types.d.ts +3 -1
  356. package/dist/core/provisioning/synchronizer/client/types.d.ts.map +1 -1
  357. package/dist/core/provisioning/synchronizer/entity-resolver.d.ts +4 -1
  358. package/dist/core/provisioning/synchronizer/entity-resolver.d.ts.map +1 -1
  359. package/dist/core/provisioning/synchronizer/entity-resolver.mjs +14 -29
  360. package/dist/core/provisioning/synchronizer/entity-resolver.mjs.map +1 -1
  361. package/dist/core/provisioning/synchronizer/index.d.ts +1 -0
  362. package/dist/core/provisioning/synchronizer/index.d.ts.map +1 -1
  363. package/dist/core/provisioning/synchronizer/realm/module.d.ts.map +1 -1
  364. package/dist/core/provisioning/synchronizer/realm/module.mjs +8 -8
  365. package/dist/core/provisioning/synchronizer/realm/module.mjs.map +1 -1
  366. package/dist/core/provisioning/synchronizer/types.d.ts +11 -0
  367. package/dist/core/provisioning/synchronizer/types.d.ts.map +1 -0
  368. package/dist/core/provisioning/synchronizer/types.mjs +4 -0
  369. package/dist/core/query/describe.d.ts +25 -0
  370. package/dist/core/query/describe.d.ts.map +1 -0
  371. package/dist/core/query/describe.mjs +50 -0
  372. package/dist/core/query/describe.mjs.map +1 -0
  373. package/dist/core/query/fields.d.ts +44 -0
  374. package/dist/core/query/fields.d.ts.map +1 -0
  375. package/dist/core/query/fields.mjs +46 -0
  376. package/dist/core/query/fields.mjs.map +1 -0
  377. package/dist/core/query/index.d.ts +1 -0
  378. package/dist/core/query/index.d.ts.map +1 -1
  379. package/dist/core/query/index.mjs +2 -1
  380. package/dist/core/query/module.d.ts +1 -1
  381. package/dist/core/query/module.mjs +1 -1
  382. package/dist/core/query/module.mjs.map +1 -1
  383. package/dist/index.mjs +6 -2
  384. package/dist/swagger.json +852 -145
  385. package/dist/ui/client/.vite/ssr-manifest.json +862 -754
  386. package/dist/ui/client/assets/index-Bk6-OZy9.css +2 -0
  387. package/dist/ui/client/assets/index-DO6_7NTJ.js +106 -0
  388. package/dist/ui/client/index.html +2 -2
  389. package/dist/ui/server/server.js +152569 -156411
  390. package/package.json +40 -40
  391. package/dist/cli/commands/reset.d.ts +0 -2
  392. package/dist/cli/commands/reset.d.ts.map +0 -1
  393. package/dist/cli/commands/reset.mjs +0 -23
  394. package/dist/cli/commands/reset.mjs.map +0 -1
  395. package/dist/components/database/index.d.ts +0 -2
  396. package/dist/components/database/index.d.ts.map +0 -1
  397. package/dist/components/database/index.mjs +0 -7
  398. package/dist/components/database/unique-entries/factory.d.ts +0 -4
  399. package/dist/components/database/unique-entries/factory.d.ts.map +0 -1
  400. package/dist/components/database/unique-entries/factory.mjs +0 -12
  401. package/dist/components/database/unique-entries/factory.mjs.map +0 -1
  402. package/dist/components/database/unique-entries/index.d.ts +0 -3
  403. package/dist/components/database/unique-entries/index.d.ts.map +0 -1
  404. package/dist/components/database/unique-entries/index.mjs +0 -6
  405. package/dist/components/database/unique-entries/module.d.ts +0 -15
  406. package/dist/components/database/unique-entries/module.d.ts.map +0 -1
  407. package/dist/components/database/unique-entries/module.mjs +0 -69
  408. package/dist/components/database/unique-entries/module.mjs.map +0 -1
  409. package/dist/ui/client/assets/index-CiHrf73J.css +0 -2
  410. package/dist/ui/client/assets/index-mtJngmng.js +0 -131
@@ -1 +1 @@
1
- {"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../../../../src/adapters/database/domains/role/entity.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAG,MAAM,kBAAkB,CAAC;AAe7D,qBAEa,UAAW,YAAW,IAAI;IAEnC,EAAE,EAAE,MAAM,CAAC;IAOX,OAAO,EAAE,OAAO,CAAC;IAMjB,IAAI,EAAE,MAAM,CAAC;IAQb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAM3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAO3B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAMtB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAO9B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAMtB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAO5B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAKpB,SAAS,EAAE,MAAM,CAAC;IAGlB,SAAS,EAAE,MAAM,CAAC;CACrB"}
1
+ {"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../../../../src/adapters/database/domains/role/entity.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAG,MAAM,kBAAkB,CAAC;AAgB7D,qBAEa,UAAW,YAAW,IAAI;IAEnC,EAAE,EAAE,MAAM,CAAC;IAOX,OAAO,EAAE,OAAO,CAAC;IAMjB,IAAI,EAAE,MAAM,CAAC;IAQb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAM3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAO3B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAMtB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAO9B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAMtB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAO5B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAKpB,SAAS,EAAE,MAAM,CAAC;IAGlB,SAAS,EAAE,MAAM,CAAC;CACrB"}
@@ -5,6 +5,7 @@ import { dateToISOStringTransformer } from "../../helpers/date.mjs";
5
5
  import "../../helpers/index.mjs";
6
6
  import { RealmEntity } from "../realm/entity.mjs";
7
7
  import "../realm/index.mjs";
8
+ import { ClientEntity } from "../client/entity.mjs";
8
9
  import { Column, CreateDateColumn, Entity, Index, JoinColumn, ManyToOne, PrimaryGeneratedColumn, Unique, UpdateDateColumn } from "typeorm";
9
10
  //#region src/adapters/database/domains/role/entity.ts
10
11
  function _ts_decorate(decorators, target, key, desc) {
@@ -64,7 +65,7 @@ _ts_decorate([
64
65
  _ts_metadata("design:type", Object)
65
66
  ], RoleEntity.prototype, "clientId", void 0);
66
67
  _ts_decorate([
67
- ManyToOne(() => RealmEntity, {
68
+ ManyToOne(() => ClientEntity, {
68
69
  onDelete: "SET NULL",
69
70
  nullable: true
70
71
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"entity.mjs","names":["Column","CreateDateColumn","Entity","Index","JoinColumn","ManyToOne","PrimaryGeneratedColumn","Unique","UpdateDateColumn","dateToISOStringTransformer","RealmEntity","RoleEntity","id","builtIn","name","displayName","description","target","clientId","client","realmId","realm","createdAt","updatedAt","type","default","length","nullable","onDelete","transformer"],"sources":["../../../../../src/adapters/database/domains/role/entity.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-2021.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { Client, Realm, Role } from '@authup/core-kit';\nimport {\n Column,\n CreateDateColumn,\n Entity,\n Index,\n JoinColumn,\n ManyToOne,\n PrimaryGeneratedColumn,\n Unique,\n UpdateDateColumn,\n} from 'typeorm';\nimport { dateToISOStringTransformer } from '../../helpers/index.ts';\nimport { RealmEntity } from '../realm/index.ts';\n\n@Entity({ name: 'auth_roles' })\n@Unique(['name', 'clientId', 'realmId'])\nexport class RoleEntity implements Role {\n @PrimaryGeneratedColumn('uuid')\n id: string;\n\n @Column({\n name: 'built_in', \n type: 'boolean', \n default: false, \n })\n builtIn: boolean;\n\n @Column({\n type: 'varchar',\n length: 128, \n })\n name: string;\n\n @Column({\n name: 'display_name', \n type: 'varchar', \n length: 256, \n nullable: true, \n })\n displayName: string | null;\n\n @Column({\n type: 'text',\n nullable: true, \n })\n description: string | null;\n\n @Column({\n type: 'varchar',\n length: 16,\n nullable: true, \n })\n target: string | null;\n\n // ------------------------------------------------------------------\n\n @Index()\n @Column({ name: 'client_id', nullable: true })\n clientId: Client['id'] | null;\n\n @ManyToOne(() => RealmEntity, {\n onDelete: 'SET NULL',\n nullable: true, \n })\n @JoinColumn({ name: 'client_id' })\n client: Client | null;\n\n // ------------------------------------------------------------------\n\n @Index()\n @Column({ name: 'realm_id', nullable: true })\n realmId: Realm['id'] | null;\n\n @ManyToOne(() => RealmEntity, {\n onDelete: 'CASCADE',\n nullable: true, \n })\n @JoinColumn({ name: 'realm_id' })\n realm: Realm | null;\n\n // ------------------------------------------------------------------\n\n @CreateDateColumn({ name: 'created_at', transformer: dateToISOStringTransformer })\n createdAt: string;\n\n @UpdateDateColumn({ name: 'updated_at', transformer: dateToISOStringTransformer })\n updatedAt: string;\n}\n"],"mappings":";;;;;;;;;AAKC,SAAA,aAAA,YAAA,QAAA,KAAA,MAAA;;;;;;;;;AAmBD,IAAaW,aAAb,MAAaA;CAETC;CAOAC;CAMAC;CAQAC;CAMAC;CAOAC;CAMAC;CAOAC;CAMAC;CAOAC;CAKAC;CAGAC;AACJ;;;CAlEQT,MAAM;CACNU,MAAM;CACNC,SAAS;;;CAKTD,MAAM;CACNE,QAAQ;;;CAKRZ,MAAM;CACNU,MAAM;CACNE,QAAQ;CACRC,UAAU;;;CAKVH,MAAM;CACNG,UAAU;;;CAKVH,MAAM;CACNE,QAAQ;CACRC,UAAU;;;;;EAOJb,MAAM;EAAaa,UAAU;;;;;CAGtBjB,gBAAAA,aAAAA;EACbkB,UAAU;EACVD,UAAU;;CAEAb,WAAAA,EAAAA,MAAM,YAAA,CAAA;;;;;;EAMVA,MAAM;EAAYa,UAAU;;;;;CAGrBjB,gBAAAA,aAAAA;EACbkB,UAAU;EACVD,UAAU;;CAEAb,WAAAA,EAAAA,MAAM,WAAA,CAAA;;;;CAKAA,MAAM;CAAce,aAAapB;;;CAGjCK,MAAM;CAAce,aAAapB;;AAvE/CK,aAAAA,aAAAA,CAAAA,OAAAA,EAAAA,MAAM,aAAA,CAAA,GAAA,OAAA;CACP;CAAQ;CAAY"}
1
+ {"version":3,"file":"entity.mjs","names":["Column","CreateDateColumn","Entity","Index","JoinColumn","ManyToOne","PrimaryGeneratedColumn","Unique","UpdateDateColumn","dateToISOStringTransformer","ClientEntity","RealmEntity","RoleEntity","id","builtIn","name","displayName","description","target","clientId","client","realmId","realm","createdAt","updatedAt","type","default","length","nullable","onDelete","transformer"],"sources":["../../../../../src/adapters/database/domains/role/entity.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-2021.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { Client, Realm, Role } from '@authup/core-kit';\nimport {\n Column,\n CreateDateColumn,\n Entity,\n Index,\n JoinColumn,\n ManyToOne,\n PrimaryGeneratedColumn,\n Unique,\n UpdateDateColumn,\n} from 'typeorm';\nimport { dateToISOStringTransformer } from '../../helpers/index.ts';\nimport { ClientEntity } from '../client/entity.ts';\nimport { RealmEntity } from '../realm/index.ts';\n\n@Entity({ name: 'auth_roles' })\n@Unique(['name', 'clientId', 'realmId'])\nexport class RoleEntity implements Role {\n @PrimaryGeneratedColumn('uuid')\n id: string;\n\n @Column({\n name: 'built_in', \n type: 'boolean', \n default: false, \n })\n builtIn: boolean;\n\n @Column({\n type: 'varchar',\n length: 128, \n })\n name: string;\n\n @Column({\n name: 'display_name', \n type: 'varchar', \n length: 256, \n nullable: true, \n })\n displayName: string | null;\n\n @Column({\n type: 'text',\n nullable: true, \n })\n description: string | null;\n\n @Column({\n type: 'varchar',\n length: 16,\n nullable: true, \n })\n target: string | null;\n\n // ------------------------------------------------------------------\n\n @Index()\n @Column({ name: 'client_id', nullable: true })\n clientId: Client['id'] | null;\n\n @ManyToOne(() => ClientEntity, {\n onDelete: 'SET NULL',\n nullable: true,\n })\n @JoinColumn({ name: 'client_id' })\n client: Client | null;\n\n // ------------------------------------------------------------------\n\n @Index()\n @Column({ name: 'realm_id', nullable: true })\n realmId: Realm['id'] | null;\n\n @ManyToOne(() => RealmEntity, {\n onDelete: 'CASCADE',\n nullable: true, \n })\n @JoinColumn({ name: 'realm_id' })\n realm: Realm | null;\n\n // ------------------------------------------------------------------\n\n @CreateDateColumn({ name: 'created_at', transformer: dateToISOStringTransformer })\n createdAt: string;\n\n @UpdateDateColumn({ name: 'updated_at', transformer: dateToISOStringTransformer })\n updatedAt: string;\n}\n"],"mappings":";;;;;;;;;;AAKC,SAAA,aAAA,YAAA,QAAA,KAAA,MAAA;;;;;;;;;AAoBD,IAAaY,aAAb,MAAaA;CAETC;CAOAC;CAMAC;CAQAC;CAMAC;CAOAC;CAMAC;CAOAC;CAMAC;CAOAC;CAKAC;CAGAC;AACJ;;;CAlEQT,MAAM;CACNU,MAAM;CACNC,SAAS;;;CAKTD,MAAM;CACNE,QAAQ;;;CAKRZ,MAAM;CACNU,MAAM;CACNE,QAAQ;CACRC,UAAU;;;CAKVH,MAAM;CACNG,UAAU;;;CAKVH,MAAM;CACNE,QAAQ;CACRC,UAAU;;;;;EAOJb,MAAM;EAAaa,UAAU;;;;;CAGtBlB,gBAAAA,cAAAA;EACbmB,UAAU;EACVD,UAAU;;CAEAb,WAAAA,EAAAA,MAAM,YAAA,CAAA;;;;;;EAMVA,MAAM;EAAYa,UAAU;;;;;CAGrBjB,gBAAAA,aAAAA;EACbkB,UAAU;EACVD,UAAU;;CAEAb,WAAAA,EAAAA,MAAM,WAAA,CAAA;;;;CAKAA,MAAM;CAAce,aAAarB;;;CAGjCM,MAAM;CAAce,aAAarB;;AAvE/CM,aAAAA,aAAAA,CAAAA,OAAAA,EAAAA,MAAM,aAAA,CAAA,GAAA,OAAA;CACP;CAAQ;CAAY"}
@@ -0,0 +1,25 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+ /**
3
+ * Re-targets auth_roles.client_id onto auth_clients. The column has
4
+ * referenced auth_realms(id) since 1740991051622 — a copy-paste of the
5
+ * realm relation on the entity (`@ManyToOne(() => RealmEntity)` on the
6
+ * client join column), so a client-scoped role could never store an
7
+ * actual client id. Same defect (and same fix) as the
8
+ * auth_permissions.client_id re-target in 1766830857009; the constraint
9
+ * name is unchanged because TypeORM derives it from the table and
10
+ * column names, not the referenced table.
11
+ *
12
+ * Any surviving non-null client_id is a realm id (that is what the old
13
+ * FK enforced) and cannot be interpreted as a client, so the reference is
14
+ * nulled — never the role row itself: the role, its permission junctions
15
+ * and its user assignments are legitimate, only the column value is
16
+ * noise (and role.clientId does not scope evaluation-time permission
17
+ * loading, so nulling widens nothing). down() restores the previous
18
+ * auth_realms target, nulling values the old constraint would reject.
19
+ */
20
+ export declare class RoleClientForeignKey1784970000000 implements MigrationInterface {
21
+ name: string;
22
+ up(queryRunner: QueryRunner): Promise<void>;
23
+ down(queryRunner: QueryRunner): Promise<void>;
24
+ }
25
+ //# sourceMappingURL=1784970000000-RoleClientForeignKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1784970000000-RoleClientForeignKey.d.ts","sourceRoot":"","sources":["../../../../../src/adapters/database/migrations/mysql/1784970000000-RoleClientForeignKey.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iCAAkC,YAAW,kBAAkB;IACxE,IAAI,SAAuC;IAE9B,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB3C,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAgB7D"}
@@ -0,0 +1,60 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ //#region src/adapters/database/migrations/mysql/1784970000000-RoleClientForeignKey.ts
5
+ /**
6
+ * Re-targets auth_roles.client_id onto auth_clients. The column has
7
+ * referenced auth_realms(id) since 1740991051622 — a copy-paste of the
8
+ * realm relation on the entity (`@ManyToOne(() => RealmEntity)` on the
9
+ * client join column), so a client-scoped role could never store an
10
+ * actual client id. Same defect (and same fix) as the
11
+ * auth_permissions.client_id re-target in 1766830857009; the constraint
12
+ * name is unchanged because TypeORM derives it from the table and
13
+ * column names, not the referenced table.
14
+ *
15
+ * Any surviving non-null client_id is a realm id (that is what the old
16
+ * FK enforced) and cannot be interpreted as a client, so the reference is
17
+ * nulled — never the role row itself: the role, its permission junctions
18
+ * and its user assignments are legitimate, only the column value is
19
+ * noise (and role.clientId does not scope evaluation-time permission
20
+ * loading, so nulling widens nothing). down() restores the previous
21
+ * auth_realms target, nulling values the old constraint would reject.
22
+ */ var RoleClientForeignKey1784970000000 = class {
23
+ name = "RoleClientForeignKey1784970000000";
24
+ async up(queryRunner) {
25
+ await queryRunner.query(`
26
+ ALTER TABLE \`auth_roles\` DROP FOREIGN KEY \`FK_8f460e65af897b9b049f582ad0e\`
27
+ `);
28
+ await queryRunner.query(`
29
+ UPDATE \`auth_roles\`
30
+ SET \`client_id\` = NULL
31
+ WHERE \`client_id\` IS NOT NULL
32
+ AND \`client_id\` NOT IN (SELECT \`id\` FROM \`auth_clients\`)
33
+ `);
34
+ await queryRunner.query(`
35
+ ALTER TABLE \`auth_roles\`
36
+ ADD CONSTRAINT \`FK_8f460e65af897b9b049f582ad0e\` FOREIGN KEY (\`client_id\`) REFERENCES \`auth_clients\`(\`id\`) ON DELETE
37
+ SET NULL ON UPDATE NO ACTION
38
+ `);
39
+ }
40
+ async down(queryRunner) {
41
+ await queryRunner.query(`
42
+ ALTER TABLE \`auth_roles\` DROP FOREIGN KEY \`FK_8f460e65af897b9b049f582ad0e\`
43
+ `);
44
+ await queryRunner.query(`
45
+ UPDATE \`auth_roles\`
46
+ SET \`client_id\` = NULL
47
+ WHERE \`client_id\` IS NOT NULL
48
+ AND \`client_id\` NOT IN (SELECT \`id\` FROM \`auth_realms\`)
49
+ `);
50
+ await queryRunner.query(`
51
+ ALTER TABLE \`auth_roles\`
52
+ ADD CONSTRAINT \`FK_8f460e65af897b9b049f582ad0e\` FOREIGN KEY (\`client_id\`) REFERENCES \`auth_realms\`(\`id\`) ON DELETE
53
+ SET NULL ON UPDATE NO ACTION
54
+ `);
55
+ }
56
+ };
57
+ //#endregion
58
+ export { RoleClientForeignKey1784970000000 };
59
+
60
+ //# sourceMappingURL=1784970000000-RoleClientForeignKey.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1784970000000-RoleClientForeignKey.mjs","names":["RoleClientForeignKey1784970000000","name","up","queryRunner","query","down"],"sources":["../../../../../src/adapters/database/migrations/mysql/1784970000000-RoleClientForeignKey.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { MigrationInterface, QueryRunner } from 'typeorm';\n\n/**\n * Re-targets auth_roles.client_id onto auth_clients. The column has\n * referenced auth_realms(id) since 1740991051622 — a copy-paste of the\n * realm relation on the entity (`@ManyToOne(() => RealmEntity)` on the\n * client join column), so a client-scoped role could never store an\n * actual client id. Same defect (and same fix) as the\n * auth_permissions.client_id re-target in 1766830857009; the constraint\n * name is unchanged because TypeORM derives it from the table and\n * column names, not the referenced table.\n *\n * Any surviving non-null client_id is a realm id (that is what the old\n * FK enforced) and cannot be interpreted as a client, so the reference is\n * nulled — never the role row itself: the role, its permission junctions\n * and its user assignments are legitimate, only the column value is\n * noise (and role.clientId does not scope evaluation-time permission\n * loading, so nulling widens nothing). down() restores the previous\n * auth_realms target, nulling values the old constraint would reject.\n */\nexport class RoleClientForeignKey1784970000000 implements MigrationInterface {\n name = 'RoleClientForeignKey1784970000000';\n\n public async up(queryRunner: QueryRunner): Promise<void> {\n await queryRunner.query(`\n ALTER TABLE \\`auth_roles\\` DROP FOREIGN KEY \\`FK_8f460e65af897b9b049f582ad0e\\`\n `);\n await queryRunner.query(`\n UPDATE \\`auth_roles\\`\n SET \\`client_id\\` = NULL\n WHERE \\`client_id\\` IS NOT NULL\n AND \\`client_id\\` NOT IN (SELECT \\`id\\` FROM \\`auth_clients\\`)\n `);\n await queryRunner.query(`\n ALTER TABLE \\`auth_roles\\`\n ADD CONSTRAINT \\`FK_8f460e65af897b9b049f582ad0e\\` FOREIGN KEY (\\`client_id\\`) REFERENCES \\`auth_clients\\`(\\`id\\`) ON DELETE\n SET NULL ON UPDATE NO ACTION\n `);\n }\n\n public async down(queryRunner: QueryRunner): Promise<void> {\n await queryRunner.query(`\n ALTER TABLE \\`auth_roles\\` DROP FOREIGN KEY \\`FK_8f460e65af897b9b049f582ad0e\\`\n `);\n await queryRunner.query(`\n UPDATE \\`auth_roles\\`\n SET \\`client_id\\` = NULL\n WHERE \\`client_id\\` IS NOT NULL\n AND \\`client_id\\` NOT IN (SELECT \\`id\\` FROM \\`auth_realms\\`)\n `);\n await queryRunner.query(`\n ALTER TABLE \\`auth_roles\\`\n ADD CONSTRAINT \\`FK_8f460e65af897b9b049f582ad0e\\` FOREIGN KEY (\\`client_id\\`) REFERENCES \\`auth_realms\\`(\\`id\\`) ON DELETE\n SET NULL ON UPDATE NO ACTION\n `);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;GA2BA,IAAaA,oCAAb,MAAaA;CACTC,OAAO;CAEP,MAAaC,GAAGC,aAAyC;EACrD,MAAMA,YAAYC,MAAM;;SAEvB;EACD,MAAMD,YAAYC,MAAM;;;;;SAKvB;EACD,MAAMD,YAAYC,MAAM;;;;SAIvB;CACL;CAEA,MAAaC,KAAKF,aAAyC;EACvD,MAAMA,YAAYC,MAAM;;SAEvB;EACD,MAAMD,YAAYC,MAAM;;;;;SAKvB;EACD,MAAMD,YAAYC,MAAM;;;;SAIvB;CACL;AACJ"}
@@ -0,0 +1,25 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+ /**
3
+ * Re-targets auth_roles.client_id onto auth_clients. The column has
4
+ * referenced auth_realms(id) since 1740991051622 — a copy-paste of the
5
+ * realm relation on the entity (`@ManyToOne(() => RealmEntity)` on the
6
+ * client join column), so a client-scoped role could never store an
7
+ * actual client id. Same defect (and same fix) as the
8
+ * auth_permissions.client_id re-target in 1766830857009; the constraint
9
+ * name is unchanged because TypeORM derives it from the table and
10
+ * column names, not the referenced table.
11
+ *
12
+ * Any surviving non-null client_id is a realm id (that is what the old
13
+ * FK enforced) and cannot be interpreted as a client, so the reference is
14
+ * nulled — never the role row itself: the role, its permission junctions
15
+ * and its user assignments are legitimate, only the column value is
16
+ * noise (and role.clientId does not scope evaluation-time permission
17
+ * loading, so nulling widens nothing). down() restores the previous
18
+ * auth_realms target, nulling values the old constraint would reject.
19
+ */
20
+ export declare class RoleClientForeignKey1784970000000 implements MigrationInterface {
21
+ name: string;
22
+ up(queryRunner: QueryRunner): Promise<void>;
23
+ down(queryRunner: QueryRunner): Promise<void>;
24
+ }
25
+ //# sourceMappingURL=1784970000000-RoleClientForeignKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1784970000000-RoleClientForeignKey.d.ts","sourceRoot":"","sources":["../../../../../src/adapters/database/migrations/postgres/1784970000000-RoleClientForeignKey.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iCAAkC,YAAW,kBAAkB;IACxE,IAAI,SAAuC;IAE9B,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB3C,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAgB7D"}
@@ -0,0 +1,60 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ //#region src/adapters/database/migrations/postgres/1784970000000-RoleClientForeignKey.ts
5
+ /**
6
+ * Re-targets auth_roles.client_id onto auth_clients. The column has
7
+ * referenced auth_realms(id) since 1740991051622 — a copy-paste of the
8
+ * realm relation on the entity (`@ManyToOne(() => RealmEntity)` on the
9
+ * client join column), so a client-scoped role could never store an
10
+ * actual client id. Same defect (and same fix) as the
11
+ * auth_permissions.client_id re-target in 1766830857009; the constraint
12
+ * name is unchanged because TypeORM derives it from the table and
13
+ * column names, not the referenced table.
14
+ *
15
+ * Any surviving non-null client_id is a realm id (that is what the old
16
+ * FK enforced) and cannot be interpreted as a client, so the reference is
17
+ * nulled — never the role row itself: the role, its permission junctions
18
+ * and its user assignments are legitimate, only the column value is
19
+ * noise (and role.clientId does not scope evaluation-time permission
20
+ * loading, so nulling widens nothing). down() restores the previous
21
+ * auth_realms target, nulling values the old constraint would reject.
22
+ */ var RoleClientForeignKey1784970000000 = class {
23
+ name = "RoleClientForeignKey1784970000000";
24
+ async up(queryRunner) {
25
+ await queryRunner.query(`
26
+ ALTER TABLE "auth_roles" DROP CONSTRAINT "FK_8f460e65af897b9b049f582ad0e"
27
+ `);
28
+ await queryRunner.query(`
29
+ UPDATE "auth_roles"
30
+ SET "client_id" = NULL
31
+ WHERE "client_id" IS NOT NULL
32
+ AND "client_id" NOT IN (SELECT "id" FROM "auth_clients")
33
+ `);
34
+ await queryRunner.query(`
35
+ ALTER TABLE "auth_roles"
36
+ ADD CONSTRAINT "FK_8f460e65af897b9b049f582ad0e" FOREIGN KEY ("client_id") REFERENCES "auth_clients"("id") ON DELETE
37
+ SET NULL ON UPDATE NO ACTION
38
+ `);
39
+ }
40
+ async down(queryRunner) {
41
+ await queryRunner.query(`
42
+ ALTER TABLE "auth_roles" DROP CONSTRAINT "FK_8f460e65af897b9b049f582ad0e"
43
+ `);
44
+ await queryRunner.query(`
45
+ UPDATE "auth_roles"
46
+ SET "client_id" = NULL
47
+ WHERE "client_id" IS NOT NULL
48
+ AND "client_id" NOT IN (SELECT "id" FROM "auth_realms")
49
+ `);
50
+ await queryRunner.query(`
51
+ ALTER TABLE "auth_roles"
52
+ ADD CONSTRAINT "FK_8f460e65af897b9b049f582ad0e" FOREIGN KEY ("client_id") REFERENCES "auth_realms"("id") ON DELETE
53
+ SET NULL ON UPDATE NO ACTION
54
+ `);
55
+ }
56
+ };
57
+ //#endregion
58
+ export { RoleClientForeignKey1784970000000 };
59
+
60
+ //# sourceMappingURL=1784970000000-RoleClientForeignKey.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1784970000000-RoleClientForeignKey.mjs","names":["RoleClientForeignKey1784970000000","name","up","queryRunner","query","down"],"sources":["../../../../../src/adapters/database/migrations/postgres/1784970000000-RoleClientForeignKey.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { MigrationInterface, QueryRunner } from 'typeorm';\n\n/**\n * Re-targets auth_roles.client_id onto auth_clients. The column has\n * referenced auth_realms(id) since 1740991051622 — a copy-paste of the\n * realm relation on the entity (`@ManyToOne(() => RealmEntity)` on the\n * client join column), so a client-scoped role could never store an\n * actual client id. Same defect (and same fix) as the\n * auth_permissions.client_id re-target in 1766830857009; the constraint\n * name is unchanged because TypeORM derives it from the table and\n * column names, not the referenced table.\n *\n * Any surviving non-null client_id is a realm id (that is what the old\n * FK enforced) and cannot be interpreted as a client, so the reference is\n * nulled — never the role row itself: the role, its permission junctions\n * and its user assignments are legitimate, only the column value is\n * noise (and role.clientId does not scope evaluation-time permission\n * loading, so nulling widens nothing). down() restores the previous\n * auth_realms target, nulling values the old constraint would reject.\n */\nexport class RoleClientForeignKey1784970000000 implements MigrationInterface {\n name = 'RoleClientForeignKey1784970000000';\n\n public async up(queryRunner: QueryRunner): Promise<void> {\n await queryRunner.query(`\n ALTER TABLE \"auth_roles\" DROP CONSTRAINT \"FK_8f460e65af897b9b049f582ad0e\"\n `);\n await queryRunner.query(`\n UPDATE \"auth_roles\"\n SET \"client_id\" = NULL\n WHERE \"client_id\" IS NOT NULL\n AND \"client_id\" NOT IN (SELECT \"id\" FROM \"auth_clients\")\n `);\n await queryRunner.query(`\n ALTER TABLE \"auth_roles\"\n ADD CONSTRAINT \"FK_8f460e65af897b9b049f582ad0e\" FOREIGN KEY (\"client_id\") REFERENCES \"auth_clients\"(\"id\") ON DELETE\n SET NULL ON UPDATE NO ACTION\n `);\n }\n\n public async down(queryRunner: QueryRunner): Promise<void> {\n await queryRunner.query(`\n ALTER TABLE \"auth_roles\" DROP CONSTRAINT \"FK_8f460e65af897b9b049f582ad0e\"\n `);\n await queryRunner.query(`\n UPDATE \"auth_roles\"\n SET \"client_id\" = NULL\n WHERE \"client_id\" IS NOT NULL\n AND \"client_id\" NOT IN (SELECT \"id\" FROM \"auth_realms\")\n `);\n await queryRunner.query(`\n ALTER TABLE \"auth_roles\"\n ADD CONSTRAINT \"FK_8f460e65af897b9b049f582ad0e\" FOREIGN KEY (\"client_id\") REFERENCES \"auth_realms\"(\"id\") ON DELETE\n SET NULL ON UPDATE NO ACTION\n `);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;GA2BA,IAAaA,oCAAb,MAAaA;CACTC,OAAO;CAEP,MAAaC,GAAGC,aAAyC;EACrD,MAAMA,YAAYC,MAAM;;SAEvB;EACD,MAAMD,YAAYC,MAAM;;;;;SAKvB;EACD,MAAMD,YAAYC,MAAM;;;;SAIvB;CACL;CAEA,MAAaC,KAAKF,aAAyC;EACvD,MAAMA,YAAYC,MAAM;;SAEvB;EACD,MAAMD,YAAYC,MAAM;;;;;SAKvB;EACD,MAAMD,YAAYC,MAAM;;;;SAIvB;CACL;AACJ"}
@@ -61,7 +61,7 @@ var HTTPOAuth2AuthorizeGrant = class extends OAuth2AuthorizeGrant {
61
61
  }
62
62
  return this.runWith(entity, {
63
63
  confirmation,
64
- ipAddress: getRequestIP(event, { trustProxy: true }) ?? void 0,
64
+ ipAddress: getRequestIP(event) ?? void 0,
65
65
  userAgent: getRequestHeader(event, "user-agent") ?? void 0
66
66
  });
67
67
  }
@@ -1 +1 @@
1
- {"version":3,"file":"authorize.mjs","names":["isClientPublic","OAuth2GrantError","OAuth2RequestError","OAuth2TokenGrant","readRequestBody","useRequestQuery","getRequestHeader","getRequestIP","OAuth2AuthorizeGrant","assertClientGrantAllowed","extractClientCredentialsFromRequest","extractOAuth2ClientCertificateEvidence","readRealmHint","HTTPOAuth2AuthorizeGrant","codeVerifier","clientAuthenticator","realmRepository","accessPolicyEvaluator","certificateSource","ctx","runWithRequest","event","body","query","code","pickStringParam","redirectUri","malformed","clientId","clientSecret","realm","resolve","certificateEvidence","client","authenticate","id","confirmation","resolveTokenBinding","AUTHORIZATION_CODE","entity","verify","clientIsPublic","realmId","accessPolicyId","allowed","evaluate","type","sub_kind","sub","realm_id","realmName","realm_name","client_id","invalid","runWith","ipAddress","trustProxy","undefined","userAgent","key","value","length"],"sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/authorize.ts"],"sourcesContent":["/*\n * Copyright (c) 2025-2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { OAuth2TokenGrantResponse } from '@authup/specs';\nimport { isClientPublic } from '@authup/core-kit';\nimport { OAuth2GrantError, OAuth2RequestError, OAuth2TokenGrant } from '@authup/specs';\nimport { readRequestBody } from '@routup/basic/body';\nimport { useRequestQuery } from '@routup/basic/query';\nimport type { IAppEvent } from 'routup';\nimport { getRequestHeader, getRequestIP } from 'routup';\nimport { OAuth2AuthorizeGrant, assertClientGrantAllowed } from '../../../../../core/index.ts';\nimport type {\n IOAuth2AccessPolicyEvaluator,\n IOAuth2AuthorizationCodeVerifier,\n IRealmRepository,\n OAuth2ClientAuthenticator,\n} from '../../../../../core/index.ts';\nimport type { HTTPOAuth2AuthorizeGrantContext, IHTTPOAuth2Grant } from './types.ts';\nimport type { CertificateSource } from '../../../request/index.ts';\nimport {\n extractClientCredentialsFromRequest,\n extractOAuth2ClientCertificateEvidence,\n readRealmHint,\n} from './utils/index.ts';\n\nexport class HTTPOAuth2AuthorizeGrant extends OAuth2AuthorizeGrant implements IHTTPOAuth2Grant {\n protected codeVerifier : IOAuth2AuthorizationCodeVerifier;\n\n protected clientAuthenticator : OAuth2ClientAuthenticator;\n\n protected realmRepository : IRealmRepository;\n\n protected accessPolicyEvaluator? : IOAuth2AccessPolicyEvaluator;\n\n protected certificateSource: CertificateSource;\n\n constructor(ctx: HTTPOAuth2AuthorizeGrantContext) {\n super(ctx);\n\n this.codeVerifier = ctx.codeVerifier;\n this.clientAuthenticator = ctx.clientAuthenticator;\n this.realmRepository = ctx.realmRepository;\n this.accessPolicyEvaluator = ctx.accessPolicyEvaluator;\n this.certificateSource = ctx.certificateSource ?? 'disabled';\n }\n\n async runWithRequest(event: IAppEvent): Promise<OAuth2TokenGrantResponse> {\n const body = await readRequestBody(event);\n const query = useRequestQuery(event);\n\n const code = this.pickStringParam(body, query, 'code');\n const redirectUri = this.pickStringParam(body, query, 'redirect_uri');\n const codeVerifier = this.pickStringParam(body, query, 'code_verifier');\n if (!code) {\n throw OAuth2RequestError.malformed();\n }\n\n const { clientId, clientSecret } = await extractClientCredentialsFromRequest(event);\n const realm = await this.realmRepository.resolve(readRealmHint(body, query), true);\n const certificateEvidence = await extractOAuth2ClientCertificateEvidence(event, this.certificateSource);\n\n const client = await this.clientAuthenticator.authenticate(\n clientId,\n clientSecret,\n realm.id,\n certificateEvidence,\n );\n const confirmation = this.clientAuthenticator.resolveTokenBinding(client, certificateEvidence);\n\n assertClientGrantAllowed(client, OAuth2TokenGrant.AUTHORIZATION_CODE);\n\n const entity = await this.codeVerifier.verify(code, {\n redirectUri,\n codeVerifier,\n clientId: client.id,\n clientIsPublic: isClientPublic(client),\n realmId: client.realmId,\n });\n\n // Application access policy (plan 052), /token backstop: a code\n // minted before the policy was attached (or outside authorize())\n // must not redeem. The subject is built from the code-blob scalars —\n // no DB identity load; attribute-rich policies are enforced at the\n // issuance legs. Denial = invalid_grant, never access_denied here.\n if (client.accessPolicyId) {\n let allowed = false;\n if (this.accessPolicyEvaluator) {\n allowed = await this.accessPolicyEvaluator.evaluate(client.accessPolicyId, {\n type: entity.sub_kind,\n id: entity.sub,\n realmId: entity.realm_id ?? null,\n realmName: entity.realm_name ?? null,\n clientId: entity.client_id ?? null,\n });\n }\n\n if (!allowed) {\n throw OAuth2GrantError.invalid();\n }\n }\n\n return this.runWith(entity, {\n confirmation,\n ipAddress: getRequestIP(event, { trustProxy: true }) ?? undefined,\n userAgent: getRequestHeader(event, 'user-agent') ?? undefined,\n });\n }\n\n protected pickStringParam(\n body: Record<string, any> | undefined,\n query: Record<string, any> | undefined,\n key: string,\n ): string | undefined {\n const value = body?.[key] ?? query?.[key];\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA6BA,IAAaa,2BAAb,cAA8CL,qBAAAA;CAChCM;CAEAC;CAEAC;CAEAC;CAEAC;CAEV,YAAYC,KAAsC;EAC9C,MAAMA,GAAAA;EAEN,KAAKL,eAAeK,IAAIL;EACxB,KAAKC,sBAAsBI,IAAIJ;EAC/B,KAAKC,kBAAkBG,IAAIH;EAC3B,KAAKC,wBAAwBE,IAAIF;EACjC,KAAKC,oBAAoBC,IAAID,qBAAqB;CACtD;CAEA,MAAME,eAAeC,OAAqD;EACtE,MAAMC,OAAO,MAAMlB,gBAAgBiB,KAAAA;EACnC,MAAME,QAAQlB,gBAAgBgB,KAAAA;EAE9B,MAAMG,OAAO,KAAKC,gBAAgBH,MAAMC,OAAO,MAAA;EAC/C,MAAMG,cAAc,KAAKD,gBAAgBH,MAAMC,OAAO,cAAA;EACtD,MAAMT,eAAe,KAAKW,gBAAgBH,MAAMC,OAAO,eAAA;EACvD,IAAI,CAACC,MACD,MAAMtB,mBAAmByB,UAAS;EAGtC,MAAM,EAAEC,UAAUC,iBAAiB,MAAMnB,oCAAoCW,KAAAA;EAC7E,MAAMS,QAAQ,MAAM,KAAKd,gBAAgBe,QAAQnB,cAAcU,MAAMC,KAAAA,GAAQ,IAAA;EAC7E,MAAMS,sBAAsB,MAAMrB,uCAAuCU,OAAO,KAAKH,iBAAiB;EAEtG,MAAMe,SAAS,MAAM,KAAKlB,oBAAoBmB,aAC1CN,UACAC,cACAC,MAAMK,IACNH,mBAAAA;EAEJ,MAAMI,eAAe,KAAKrB,oBAAoBsB,oBAAoBJ,QAAQD,mBAAAA;EAE1EvB,yBAAyBwB,QAAQ9B,iBAAiBmC,kBAAkB;EAEpE,MAAMC,SAAS,MAAM,KAAKzB,aAAa0B,OAAOhB,MAAM;GAChDE;GACAZ;GACAc,UAAUK,OAAOE;GACjBM,gBAAgBzC,eAAeiC,MAAAA;GAC/BS,SAAST,OAAOS;EACpB,CAAA;EAOA,IAAIT,OAAOU,gBAAgB;GACvB,IAAIC,UAAU;GACd,IAAI,KAAK3B,uBACL2B,UAAU,MAAM,KAAK3B,sBAAsB4B,SAASZ,OAAOU,gBAAgB;IACvEG,MAAMP,OAAOQ;IACbZ,IAAII,OAAOS;IACXN,SAASH,OAAOU,YAAY;IAC5BC,WAAWX,OAAOY,cAAc;IAChCvB,UAAUW,OAAOa,aAAa;GAClC,CAAA;GAGJ,IAAI,CAACR,SACD,MAAM3C,iBAAiBoD,QAAO;EAEtC;EAEA,OAAO,KAAKC,QAAQf,QAAQ;GACxBH;GACAmB,WAAWhD,aAAac,OAAO,EAAEmC,YAAY,KAAK,CAAA,KAAMC,KAAAA;GACxDC,WAAWpD,iBAAiBe,OAAO,YAAA,KAAiBoC,KAAAA;EACxD,CAAA;CACJ;CAEUhC,gBACNH,MACAC,OACAoC,KACkB;EAClB,MAAMC,QAAQtC,OAAOqC,QAAQpC,QAAQoC;EACrC,OAAO,OAAOC,UAAU,YAAYA,MAAMC,SAAS,IAAID,QAAQH,KAAAA;CACnE;AACJ"}
1
+ {"version":3,"file":"authorize.mjs","names":["isClientPublic","OAuth2GrantError","OAuth2RequestError","OAuth2TokenGrant","readRequestBody","useRequestQuery","getRequestHeader","getRequestIP","OAuth2AuthorizeGrant","assertClientGrantAllowed","extractClientCredentialsFromRequest","extractOAuth2ClientCertificateEvidence","readRealmHint","HTTPOAuth2AuthorizeGrant","codeVerifier","clientAuthenticator","realmRepository","accessPolicyEvaluator","certificateSource","ctx","runWithRequest","event","body","query","code","pickStringParam","redirectUri","malformed","clientId","clientSecret","realm","resolve","certificateEvidence","client","authenticate","id","confirmation","resolveTokenBinding","AUTHORIZATION_CODE","entity","verify","clientIsPublic","realmId","accessPolicyId","allowed","evaluate","type","sub_kind","sub","realm_id","realmName","realm_name","client_id","invalid","runWith","ipAddress","undefined","userAgent","key","value","length"],"sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/authorize.ts"],"sourcesContent":["/*\n * Copyright (c) 2025-2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { OAuth2TokenGrantResponse } from '@authup/specs';\nimport { isClientPublic } from '@authup/core-kit';\nimport { OAuth2GrantError, OAuth2RequestError, OAuth2TokenGrant } from '@authup/specs';\nimport { readRequestBody } from '@routup/basic/body';\nimport { useRequestQuery } from '@routup/basic/query';\nimport type { IAppEvent } from 'routup';\nimport { getRequestHeader, getRequestIP } from 'routup';\nimport { OAuth2AuthorizeGrant, assertClientGrantAllowed } from '../../../../../core/index.ts';\nimport type {\n IOAuth2AccessPolicyEvaluator,\n IOAuth2AuthorizationCodeVerifier,\n IRealmRepository,\n OAuth2ClientAuthenticator,\n} from '../../../../../core/index.ts';\nimport type { HTTPOAuth2AuthorizeGrantContext, IHTTPOAuth2Grant } from './types.ts';\nimport type { CertificateSource } from '../../../request/index.ts';\nimport {\n extractClientCredentialsFromRequest,\n extractOAuth2ClientCertificateEvidence,\n readRealmHint,\n} from './utils/index.ts';\n\nexport class HTTPOAuth2AuthorizeGrant extends OAuth2AuthorizeGrant implements IHTTPOAuth2Grant {\n protected codeVerifier : IOAuth2AuthorizationCodeVerifier;\n\n protected clientAuthenticator : OAuth2ClientAuthenticator;\n\n protected realmRepository : IRealmRepository;\n\n protected accessPolicyEvaluator? : IOAuth2AccessPolicyEvaluator;\n\n protected certificateSource: CertificateSource;\n\n constructor(ctx: HTTPOAuth2AuthorizeGrantContext) {\n super(ctx);\n\n this.codeVerifier = ctx.codeVerifier;\n this.clientAuthenticator = ctx.clientAuthenticator;\n this.realmRepository = ctx.realmRepository;\n this.accessPolicyEvaluator = ctx.accessPolicyEvaluator;\n this.certificateSource = ctx.certificateSource ?? 'disabled';\n }\n\n async runWithRequest(event: IAppEvent): Promise<OAuth2TokenGrantResponse> {\n const body = await readRequestBody(event);\n const query = useRequestQuery(event);\n\n const code = this.pickStringParam(body, query, 'code');\n const redirectUri = this.pickStringParam(body, query, 'redirect_uri');\n const codeVerifier = this.pickStringParam(body, query, 'code_verifier');\n if (!code) {\n throw OAuth2RequestError.malformed();\n }\n\n const { clientId, clientSecret } = await extractClientCredentialsFromRequest(event);\n const realm = await this.realmRepository.resolve(readRealmHint(body, query), true);\n const certificateEvidence = await extractOAuth2ClientCertificateEvidence(event, this.certificateSource);\n\n const client = await this.clientAuthenticator.authenticate(\n clientId,\n clientSecret,\n realm.id,\n certificateEvidence,\n );\n const confirmation = this.clientAuthenticator.resolveTokenBinding(client, certificateEvidence);\n\n assertClientGrantAllowed(client, OAuth2TokenGrant.AUTHORIZATION_CODE);\n\n const entity = await this.codeVerifier.verify(code, {\n redirectUri,\n codeVerifier,\n clientId: client.id,\n clientIsPublic: isClientPublic(client),\n realmId: client.realmId,\n });\n\n // Application access policy (plan 052), /token backstop: a code\n // minted before the policy was attached (or outside authorize())\n // must not redeem. The subject is built from the code-blob scalars —\n // no DB identity load; attribute-rich policies are enforced at the\n // issuance legs. Denial = invalid_grant, never access_denied here.\n if (client.accessPolicyId) {\n let allowed = false;\n if (this.accessPolicyEvaluator) {\n allowed = await this.accessPolicyEvaluator.evaluate(client.accessPolicyId, {\n type: entity.sub_kind,\n id: entity.sub,\n realmId: entity.realm_id ?? null,\n realmName: entity.realm_name ?? null,\n clientId: entity.client_id ?? null,\n });\n }\n\n if (!allowed) {\n throw OAuth2GrantError.invalid();\n }\n }\n\n return this.runWith(entity, {\n confirmation,\n ipAddress: getRequestIP(event) ?? undefined,\n userAgent: getRequestHeader(event, 'user-agent') ?? undefined,\n });\n }\n\n protected pickStringParam(\n body: Record<string, any> | undefined,\n query: Record<string, any> | undefined,\n key: string,\n ): string | undefined {\n const value = body?.[key] ?? query?.[key];\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA6BA,IAAaa,2BAAb,cAA8CL,qBAAAA;CAChCM;CAEAC;CAEAC;CAEAC;CAEAC;CAEV,YAAYC,KAAsC;EAC9C,MAAMA,GAAAA;EAEN,KAAKL,eAAeK,IAAIL;EACxB,KAAKC,sBAAsBI,IAAIJ;EAC/B,KAAKC,kBAAkBG,IAAIH;EAC3B,KAAKC,wBAAwBE,IAAIF;EACjC,KAAKC,oBAAoBC,IAAID,qBAAqB;CACtD;CAEA,MAAME,eAAeC,OAAqD;EACtE,MAAMC,OAAO,MAAMlB,gBAAgBiB,KAAAA;EACnC,MAAME,QAAQlB,gBAAgBgB,KAAAA;EAE9B,MAAMG,OAAO,KAAKC,gBAAgBH,MAAMC,OAAO,MAAA;EAC/C,MAAMG,cAAc,KAAKD,gBAAgBH,MAAMC,OAAO,cAAA;EACtD,MAAMT,eAAe,KAAKW,gBAAgBH,MAAMC,OAAO,eAAA;EACvD,IAAI,CAACC,MACD,MAAMtB,mBAAmByB,UAAS;EAGtC,MAAM,EAAEC,UAAUC,iBAAiB,MAAMnB,oCAAoCW,KAAAA;EAC7E,MAAMS,QAAQ,MAAM,KAAKd,gBAAgBe,QAAQnB,cAAcU,MAAMC,KAAAA,GAAQ,IAAA;EAC7E,MAAMS,sBAAsB,MAAMrB,uCAAuCU,OAAO,KAAKH,iBAAiB;EAEtG,MAAMe,SAAS,MAAM,KAAKlB,oBAAoBmB,aAC1CN,UACAC,cACAC,MAAMK,IACNH,mBAAAA;EAEJ,MAAMI,eAAe,KAAKrB,oBAAoBsB,oBAAoBJ,QAAQD,mBAAAA;EAE1EvB,yBAAyBwB,QAAQ9B,iBAAiBmC,kBAAkB;EAEpE,MAAMC,SAAS,MAAM,KAAKzB,aAAa0B,OAAOhB,MAAM;GAChDE;GACAZ;GACAc,UAAUK,OAAOE;GACjBM,gBAAgBzC,eAAeiC,MAAAA;GAC/BS,SAAST,OAAOS;EACpB,CAAA;EAOA,IAAIT,OAAOU,gBAAgB;GACvB,IAAIC,UAAU;GACd,IAAI,KAAK3B,uBACL2B,UAAU,MAAM,KAAK3B,sBAAsB4B,SAASZ,OAAOU,gBAAgB;IACvEG,MAAMP,OAAOQ;IACbZ,IAAII,OAAOS;IACXN,SAASH,OAAOU,YAAY;IAC5BC,WAAWX,OAAOY,cAAc;IAChCvB,UAAUW,OAAOa,aAAa;GAClC,CAAA;GAGJ,IAAI,CAACR,SACD,MAAM3C,iBAAiBoD,QAAO;EAEtC;EAEA,OAAO,KAAKC,QAAQf,QAAQ;GACxBH;GACAmB,WAAWhD,aAAac,KAAAA,KAAUmC,KAAAA;GAClCC,WAAWnD,iBAAiBe,OAAO,YAAA,KAAiBmC,KAAAA;EACxD,CAAA;CACJ;CAEU/B,gBACNH,MACAC,OACAmC,KACkB;EAClB,MAAMC,QAAQrC,OAAOoC,QAAQnC,QAAQmC;EACrC,OAAO,OAAOC,UAAU,YAAYA,MAAMC,SAAS,IAAID,QAAQH,KAAAA;CACnE;AACJ"}
@@ -31,7 +31,7 @@ var HTTPClientCredentialsGrant = class extends ClientCredentialsGrant {
31
31
  assertClientGrantAllowed(client, OAuth2TokenGrant.CLIENT_CREDENTIALS);
32
32
  return this.runWith(client, {
33
33
  confirmation,
34
- ipAddress: getRequestIP(event, { trustProxy: true }) ?? void 0,
34
+ ipAddress: getRequestIP(event) ?? void 0,
35
35
  userAgent: getRequestHeader(event, "user-agent") ?? void 0
36
36
  });
37
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client-credentials.mjs","names":["OAuth2ClientError","OAuth2TokenGrant","readRequestBody","ClientAuthMethod","getRequestHeader","getRequestIP","ClientCredentialsGrant","assertClientGrantAllowed","extractClientCredentialsFromRequest","extractOAuth2ClientCertificateEvidence","HTTPClientCredentialsGrant","clientAuthenticator","certificateSource","ctx","runWithRequest","event","clientId","clientSecret","body","realmId","realm_id","invalid","certificateEvidence","client","authenticate","authMethod","NONE","confirmation","resolveTokenBinding","CLIENT_CREDENTIALS","runWith","ipAddress","trustProxy","undefined","userAgent"],"sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/client-credentials.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 { OAuth2TokenGrantResponse } from '@authup/specs';\nimport { OAuth2ClientError, OAuth2TokenGrant } from '@authup/specs';\nimport { readRequestBody } from '@routup/basic/body';\nimport { ClientAuthMethod } from '@authup/core-kit';\nimport type { IAppEvent } from 'routup';\nimport { getRequestHeader, getRequestIP } from 'routup';\nimport type { OAuth2ClientAuthenticator } from '../../../../../core/index.ts';\nimport { ClientCredentialsGrant, assertClientGrantAllowed } from '../../../../../core/index.ts';\nimport type { HTTPOAuth2ClientCredentialsGrantContext, IHTTPOAuth2Grant } from './types.ts';\nimport type { CertificateSource } from '../../../request/index.ts';\nimport {\n extractClientCredentialsFromRequest,\n extractOAuth2ClientCertificateEvidence,\n} from './utils/index.ts';\n\nexport class HTTPClientCredentialsGrant extends ClientCredentialsGrant implements IHTTPOAuth2Grant {\n protected clientAuthenticator : OAuth2ClientAuthenticator;\n\n protected certificateSource: CertificateSource;\n\n constructor(ctx: HTTPOAuth2ClientCredentialsGrantContext) {\n super(ctx);\n\n this.clientAuthenticator = ctx.clientAuthenticator;\n this.certificateSource = ctx.certificateSource ?? 'disabled';\n }\n\n async runWithRequest(event: IAppEvent): Promise<OAuth2TokenGrantResponse> {\n const { clientId, clientSecret } = await extractClientCredentialsFromRequest(event);\n const body = await readRequestBody(event);\n const realmId = body?.realm_id;\n\n if (!clientId) {\n throw OAuth2ClientError.invalid();\n }\n\n const certificateEvidence = await extractOAuth2ClientCertificateEvidence(event, this.certificateSource);\n const client = await this.clientAuthenticator.authenticate(\n clientId,\n clientSecret,\n realmId,\n certificateEvidence,\n );\n if (client.authMethod === ClientAuthMethod.NONE) {\n throw OAuth2ClientError.invalid();\n }\n const confirmation = this.clientAuthenticator.resolveTokenBinding(client, certificateEvidence);\n\n assertClientGrantAllowed(client, OAuth2TokenGrant.CLIENT_CREDENTIALS);\n\n return this.runWith(client, {\n confirmation,\n ipAddress: getRequestIP(event, { trustProxy: true }) ?? undefined,\n userAgent: getRequestHeader(event, 'user-agent') ?? undefined,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAsBA,IAAaU,6BAAb,cAAgDJ,uBAAAA;CAClCK;CAEAC;CAEV,YAAYC,KAA8C;EACtD,MAAMA,GAAAA;EAEN,KAAKF,sBAAsBE,IAAIF;EAC/B,KAAKC,oBAAoBC,IAAID,qBAAqB;CACtD;CAEA,MAAME,eAAeC,OAAqD;EACtE,MAAM,EAAEC,UAAUC,iBAAiB,MAAMT,oCAAoCO,KAAAA;EAE7E,MAAMI,WAAUD,MADGhB,gBAAgBa,KAAAA,EAAAA,EACbK;EAEtB,IAAI,CAACJ,UACD,MAAMhB,kBAAkBqB,QAAO;EAGnC,MAAMC,sBAAsB,MAAMb,uCAAuCM,OAAO,KAAKH,iBAAiB;EACtG,MAAMW,SAAS,MAAM,KAAKZ,oBAAoBa,aAC1CR,UACAC,cACAE,SACAG,mBAAAA;EAEJ,IAAIC,OAAOE,eAAetB,iBAAiBuB,MACvC,MAAM1B,kBAAkBqB,QAAO;EAEnC,MAAMM,eAAe,KAAKhB,oBAAoBiB,oBAAoBL,QAAQD,mBAAAA;EAE1Ef,yBAAyBgB,QAAQtB,iBAAiB4B,kBAAkB;EAEpE,OAAO,KAAKC,QAAQP,QAAQ;GACxBI;GACAI,WAAW1B,aAAaU,OAAO,EAAEiB,YAAY,KAAK,CAAA,KAAMC,KAAAA;GACxDC,WAAW9B,iBAAiBW,OAAO,YAAA,KAAiBkB,KAAAA;EACxD,CAAA;CACJ;AACJ"}
1
+ {"version":3,"file":"client-credentials.mjs","names":["OAuth2ClientError","OAuth2TokenGrant","readRequestBody","ClientAuthMethod","getRequestHeader","getRequestIP","ClientCredentialsGrant","assertClientGrantAllowed","extractClientCredentialsFromRequest","extractOAuth2ClientCertificateEvidence","HTTPClientCredentialsGrant","clientAuthenticator","certificateSource","ctx","runWithRequest","event","clientId","clientSecret","body","realmId","realm_id","invalid","certificateEvidence","client","authenticate","authMethod","NONE","confirmation","resolveTokenBinding","CLIENT_CREDENTIALS","runWith","ipAddress","undefined","userAgent"],"sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/client-credentials.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 { OAuth2TokenGrantResponse } from '@authup/specs';\nimport { OAuth2ClientError, OAuth2TokenGrant } from '@authup/specs';\nimport { readRequestBody } from '@routup/basic/body';\nimport { ClientAuthMethod } from '@authup/core-kit';\nimport type { IAppEvent } from 'routup';\nimport { getRequestHeader, getRequestIP } from 'routup';\nimport type { OAuth2ClientAuthenticator } from '../../../../../core/index.ts';\nimport { ClientCredentialsGrant, assertClientGrantAllowed } from '../../../../../core/index.ts';\nimport type { HTTPOAuth2ClientCredentialsGrantContext, IHTTPOAuth2Grant } from './types.ts';\nimport type { CertificateSource } from '../../../request/index.ts';\nimport {\n extractClientCredentialsFromRequest,\n extractOAuth2ClientCertificateEvidence,\n} from './utils/index.ts';\n\nexport class HTTPClientCredentialsGrant extends ClientCredentialsGrant implements IHTTPOAuth2Grant {\n protected clientAuthenticator : OAuth2ClientAuthenticator;\n\n protected certificateSource: CertificateSource;\n\n constructor(ctx: HTTPOAuth2ClientCredentialsGrantContext) {\n super(ctx);\n\n this.clientAuthenticator = ctx.clientAuthenticator;\n this.certificateSource = ctx.certificateSource ?? 'disabled';\n }\n\n async runWithRequest(event: IAppEvent): Promise<OAuth2TokenGrantResponse> {\n const { clientId, clientSecret } = await extractClientCredentialsFromRequest(event);\n const body = await readRequestBody(event);\n const realmId = body?.realm_id;\n\n if (!clientId) {\n throw OAuth2ClientError.invalid();\n }\n\n const certificateEvidence = await extractOAuth2ClientCertificateEvidence(event, this.certificateSource);\n const client = await this.clientAuthenticator.authenticate(\n clientId,\n clientSecret,\n realmId,\n certificateEvidence,\n );\n if (client.authMethod === ClientAuthMethod.NONE) {\n throw OAuth2ClientError.invalid();\n }\n const confirmation = this.clientAuthenticator.resolveTokenBinding(client, certificateEvidence);\n\n assertClientGrantAllowed(client, OAuth2TokenGrant.CLIENT_CREDENTIALS);\n\n return this.runWith(client, {\n confirmation,\n ipAddress: getRequestIP(event) ?? undefined,\n userAgent: getRequestHeader(event, 'user-agent') ?? undefined,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAsBA,IAAaU,6BAAb,cAAgDJ,uBAAAA;CAClCK;CAEAC;CAEV,YAAYC,KAA8C;EACtD,MAAMA,GAAAA;EAEN,KAAKF,sBAAsBE,IAAIF;EAC/B,KAAKC,oBAAoBC,IAAID,qBAAqB;CACtD;CAEA,MAAME,eAAeC,OAAqD;EACtE,MAAM,EAAEC,UAAUC,iBAAiB,MAAMT,oCAAoCO,KAAAA;EAE7E,MAAMI,WAAUD,MADGhB,gBAAgBa,KAAAA,EAAAA,EACbK;EAEtB,IAAI,CAACJ,UACD,MAAMhB,kBAAkBqB,QAAO;EAGnC,MAAMC,sBAAsB,MAAMb,uCAAuCM,OAAO,KAAKH,iBAAiB;EACtG,MAAMW,SAAS,MAAM,KAAKZ,oBAAoBa,aAC1CR,UACAC,cACAE,SACAG,mBAAAA;EAEJ,IAAIC,OAAOE,eAAetB,iBAAiBuB,MACvC,MAAM1B,kBAAkBqB,QAAO;EAEnC,MAAMM,eAAe,KAAKhB,oBAAoBiB,oBAAoBL,QAAQD,mBAAAA;EAE1Ef,yBAAyBgB,QAAQtB,iBAAiB4B,kBAAkB;EAEpE,OAAO,KAAKC,QAAQP,QAAQ;GACxBI;GACAI,WAAW1B,aAAaU,KAAAA,KAAUiB,KAAAA;GAClCC,WAAW7B,iBAAiBW,OAAO,YAAA,KAAiBiB,KAAAA;EACxD,CAAA;CACJ;AACJ"}
@@ -11,7 +11,7 @@ var HTTPOAuth2IdentityGrantType = class extends IdentityGrantType {
11
11
  runWithRequest(event) {
12
12
  const identity = useRequestIdentityOrFail(event);
13
13
  return this.runWith(identity.raw, {
14
- ipAddress: getRequestIP(event, { trustProxy: true }) ?? void 0,
14
+ ipAddress: getRequestIP(event) ?? void 0,
15
15
  userAgent: getRequestHeader(event, "user-agent") ?? void 0
16
16
  });
17
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"identity.mjs","names":["getRequestHeader","getRequestIP","IdentityGrantType","useRequestIdentityOrFail","HTTPOAuth2IdentityGrantType","runWithRequest","event","identity","runWith","raw","ipAddress","trustProxy","undefined","userAgent"],"sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/identity.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 { OAuth2TokenGrantResponse } from '@authup/specs';\nimport type { IAppEvent } from 'routup';\nimport { getRequestHeader, getRequestIP } from 'routup';\nimport { IdentityGrantType } from '../../../../../core/index.ts';\nimport { useRequestIdentityOrFail } from '../../../request/index.ts';\nimport type { IHTTPOAuth2Grant } from './types.ts';\n\nexport class HTTPOAuth2IdentityGrantType extends IdentityGrantType implements IHTTPOAuth2Grant {\n runWithRequest(event: IAppEvent): Promise<OAuth2TokenGrantResponse> {\n const identity = useRequestIdentityOrFail(event);\n\n return this.runWith(\n identity.raw,\n {\n ipAddress: getRequestIP(event, { trustProxy: true }) ?? undefined,\n userAgent: getRequestHeader(event, 'user-agent') ?? undefined,\n },\n );\n }\n}\n"],"mappings":";;;;;;;;;AAcA,IAAaI,8BAAb,cAAiDF,kBAAAA;CAC7CG,eAAeC,OAAqD;EAChE,MAAMC,WAAWJ,yBAAyBG,KAAAA;EAE1C,OAAO,KAAKE,QACRD,SAASE,KACT;GACIC,WAAWT,aAAaK,OAAO,EAAEK,YAAY,KAAK,CAAA,KAAMC,KAAAA;GACxDC,WAAWb,iBAAiBM,OAAO,YAAA,KAAiBM,KAAAA;EACxD,CAAA;CAER;AACJ"}
1
+ {"version":3,"file":"identity.mjs","names":["getRequestHeader","getRequestIP","IdentityGrantType","useRequestIdentityOrFail","HTTPOAuth2IdentityGrantType","runWithRequest","event","identity","runWith","raw","ipAddress","undefined","userAgent"],"sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/identity.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 { OAuth2TokenGrantResponse } from '@authup/specs';\nimport type { IAppEvent } from 'routup';\nimport { getRequestHeader, getRequestIP } from 'routup';\nimport { IdentityGrantType } from '../../../../../core/index.ts';\nimport { useRequestIdentityOrFail } from '../../../request/index.ts';\nimport type { IHTTPOAuth2Grant } from './types.ts';\n\nexport class HTTPOAuth2IdentityGrantType extends IdentityGrantType implements IHTTPOAuth2Grant {\n runWithRequest(event: IAppEvent): Promise<OAuth2TokenGrantResponse> {\n const identity = useRequestIdentityOrFail(event);\n\n return this.runWith(\n identity.raw,\n {\n ipAddress: getRequestIP(event) ?? undefined,\n userAgent: getRequestHeader(event, 'user-agent') ?? undefined,\n },\n );\n }\n}\n"],"mappings":";;;;;;;;;AAcA,IAAaI,8BAAb,cAAiDF,kBAAAA;CAC7CG,eAAeC,OAAqD;EAChE,MAAMC,WAAWJ,yBAAyBG,KAAAA;EAE1C,OAAO,KAAKE,QACRD,SAASE,KACT;GACIC,WAAWT,aAAaK,KAAAA,KAAUK,KAAAA;GAClCC,WAAWZ,iBAAiBM,OAAO,YAAA,KAAiBK,KAAAA;EACxD,CAAA;CAER;AACJ"}
@@ -46,7 +46,7 @@ var HTTPPasswordGrant = class extends PasswordGrantType {
46
46
  const client = clientId ? await this.clientAuthenticator.authenticate(clientId, clientSecret, realm.id, certificateEvidence) : void 0;
47
47
  const confirmation = client ? this.clientAuthenticator.resolveTokenBinding(client, certificateEvidence) : void 0;
48
48
  if (client) assertClientGrantAllowed(client, OAuth2TokenGrant.PASSWORD);
49
- const ipAddress = getRequestIP(event, { trustProxy: true }) ?? void 0;
49
+ const ipAddress = getRequestIP(event) ?? void 0;
50
50
  const userAgent = getRequestHeader(event, "user-agent") ?? void 0;
51
51
  const identifier = username.trim().toLowerCase();
52
52
  await this.loginThrottleService?.assertNotThrottled({
@@ -1 +1 @@
1
- {"version":3,"file":"password.mjs","names":["EventName","EventScope","UserAuthenticatorKind","isEntityCredentialsInvalidError","isEntityInactiveError","OAuth2MfaRequiredError","OAuth2RequestError","OAuth2TokenGrant","readRequestBody","getRequestHeader","getRequestIP","PasswordGrantType","assertClientGrantAllowed","guessUserAuthenticatorKindByResponse","extractClientCredentialsFromRequest","extractOAuth2ClientCertificateEvidence","readRealmHint","readStringField","HTTPPasswordGrant","authenticator","clientAuthenticator","realmRepository","loginThrottleService","userAuthenticatorService","mfaLoginService","logger","certificateSource","ctx","runWithRequest","event","body","username","password","malformed","clientId","clientSecret","realm","resolve","certificateEvidence","client","authenticate","id","undefined","confirmation","resolveTokenBinding","PASSWORD","ipAddress","trustProxy","userAgent","identifier","trim","toLowerCase","assertNotThrottled","realmId","user","e","eventService","record","scope","OAUTH2","name","LOGIN_FAILED","actorType","actorId","actorName","requestIpAddress","requestUserAgent","requestPath","path","requestMethod","method","data","errorCode","code","metrics","recordLogin","mfaVerifiedAt","verifySecondFactor","runWith","status","challenge","issueMaterial","required","otp","ticket","issueMfaTicket","kinds","message","mfa_token","token","mfa_token_expires_in","expiresIn","verified","verify","kind","response","Date","toISOString","interactive","includes","EMAIL","WEBAUTHN","issueTicket","warn","error"],"sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/password.ts"],"sourcesContent":["/*\n * Copyright (c) 2025-2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { User } from '@authup/core-kit';\nimport { EventName, EventScope, UserAuthenticatorKind } from '@authup/core-kit';\nimport type { Logger } from '@authup/server-kit';\nimport { isEntityCredentialsInvalidError, isEntityInactiveError } from '@authup/errors';\nimport type { OAuth2TokenConfirmation, OAuth2TokenGrantResponse } from '@authup/specs';\nimport { OAuth2MfaRequiredError, OAuth2RequestError, OAuth2TokenGrant } from '@authup/specs';\nimport { readRequestBody } from '@routup/basic/body';\nimport type { IAppEvent } from 'routup';\nimport { getRequestHeader, getRequestIP } from 'routup';\nimport type {\n ICredentialsAuthenticator,\n ILoginThrottleService,\n IOAuth2MfaLoginService,\n IRealmRepository,\n IUserAuthenticatorService,\n OAuth2ClientAuthenticator,\n} from '../../../../../core/index.ts';\nimport {\n PasswordGrantType,\n assertClientGrantAllowed,\n guessUserAuthenticatorKindByResponse,\n} from '../../../../../core/index.ts';\nimport type { HTTPOAuth2PasswordGrantContext, IHTTPOAuth2Grant } from './types.ts';\nimport type { CertificateSource } from '../../../request/index.ts';\nimport {\n extractClientCredentialsFromRequest,\n extractOAuth2ClientCertificateEvidence,\n readRealmHint,\n readStringField,\n} from './utils/index.ts';\n\nexport class HTTPPasswordGrant extends PasswordGrantType implements IHTTPOAuth2Grant {\n protected authenticator : ICredentialsAuthenticator<User>;\n\n protected clientAuthenticator : OAuth2ClientAuthenticator;\n\n protected realmRepository : IRealmRepository;\n\n protected loginThrottleService? : ILoginThrottleService;\n\n protected userAuthenticatorService? : IUserAuthenticatorService;\n\n protected mfaLoginService? : IOAuth2MfaLoginService;\n\n protected logger? : Logger;\n\n protected certificateSource: CertificateSource;\n\n constructor(ctx: HTTPOAuth2PasswordGrantContext) {\n super(ctx);\n\n this.authenticator = ctx.authenticator;\n this.clientAuthenticator = ctx.clientAuthenticator;\n this.realmRepository = ctx.realmRepository;\n this.loginThrottleService = ctx.loginThrottleService;\n this.userAuthenticatorService = ctx.userAuthenticatorService;\n this.mfaLoginService = ctx.mfaLoginService;\n this.logger = ctx.logger;\n this.certificateSource = ctx.certificateSource ?? 'disabled';\n }\n\n async runWithRequest(event: IAppEvent): Promise<OAuth2TokenGrantResponse> {\n const body = await readRequestBody(event);\n\n const username = readStringField(body, 'username');\n const password = readStringField(body, 'password');\n if (!username || !password) {\n throw OAuth2RequestError.malformed('username and password must be provided.');\n }\n\n const { clientId, clientSecret } = await extractClientCredentialsFromRequest(event);\n\n const realm = await this.realmRepository.resolve(readRealmHint(body), true);\n const certificateEvidence = await extractOAuth2ClientCertificateEvidence(event, this.certificateSource);\n\n const client = clientId ?\n await this.clientAuthenticator.authenticate(\n clientId,\n clientSecret,\n realm.id,\n certificateEvidence,\n ) :\n undefined;\n\n const confirmation = client ?\n this.clientAuthenticator.resolveTokenBinding(client, certificateEvidence) :\n undefined;\n\n if (client) {\n assertClientGrantAllowed(client, OAuth2TokenGrant.PASSWORD);\n }\n\n const ipAddress = getRequestIP(event, { trustProxy: true }) ?? undefined;\n const userAgent = getRequestHeader(event, 'user-agent') ?? undefined;\n\n // canonical identifier form (layer 3) — the throttle key and the\n // loginFailed actorName must match what canonically stored rows carry.\n const identifier = username.trim().toLowerCase();\n\n await this.loginThrottleService?.assertNotThrottled({\n identifier,\n ipAddress,\n realmId: realm.id,\n });\n\n let user : User;\n try {\n user = await this.authenticator.authenticate(username, password, realm.id);\n } catch (e) {\n if (isEntityCredentialsInvalidError(e) || isEntityInactiveError(e)) {\n await this.eventService?.record({\n scope: EventScope.OAUTH2,\n name: EventName.LOGIN_FAILED,\n actorType: null,\n actorId: null,\n actorName: identifier,\n clientId: client?.id ?? null,\n realmId: realm.id,\n requestIpAddress: ipAddress ?? null,\n requestUserAgent: userAgent ?? null,\n requestPath: event.path,\n requestMethod: event.method,\n data: { errorCode: e.code },\n });\n this.metrics?.recordLogin('failure');\n }\n\n throw e;\n }\n\n const mfaVerifiedAt = await this.verifySecondFactor(user, body, {\n ipAddress,\n userAgent,\n clientId: client?.id ?? null,\n confirmation,\n });\n\n return this.runWith(\n {\n user, \n client, \n mfaVerifiedAt, \n },\n {\n confirmation,\n ipAddress,\n userAgent,\n },\n );\n }\n\n /**\n * MFA gate on the direct password grant: a user holding a confirmed\n * device must send a valid `otp` form parameter (TOTP or recovery\n * code, classified by shape) — otherwise `mfa_required`. Users\n * without a device pass through (they could never enroll otherwise).\n */\n protected async verifySecondFactor(\n user: User,\n body: Record<string, any>,\n ctx: {\n ipAddress?: string, \n userAgent?: string, \n clientId: string | null,\n confirmation?: OAuth2TokenConfirmation,\n },\n ): Promise<string | undefined> {\n if (!this.userAuthenticatorService) {\n return undefined;\n }\n\n // requirement flags + kinds only — no webauthn material on the token path.\n const status = await this.userAuthenticatorService.challenge(user.id, { issueMaterial: false });\n if (!status.required) {\n return undefined;\n }\n\n const otp = readStringField(body, 'otp');\n if (!otp) {\n // carry the challengeable kinds so a client (the hosted login form)\n // can tell whether a single-POST factor (totp/recovery) is on offer\n // or the user must complete an interactive challenge (email/webauthn).\n // For the interactive kinds an \"MFA-pending\" ticket (issue #3242)\n // rides along: a restricted mfa_token-kind bearer accepted ONLY by\n // the challenge routes, backed by a short-lived pending session\n // (mfa_at: null) — never a usable access/refresh pair.\n const ticket = await this.issueMfaTicket(user, status.kinds, ctx);\n\n throw new OAuth2MfaRequiredError({\n message: 'Complete a second-factor challenge to continue.',\n data: {\n kinds: status.kinds,\n ...(ticket ? {\n mfa_token: ticket.token,\n mfa_token_expires_in: ticket.expiresIn,\n } : {}),\n },\n });\n }\n\n const verified = await this.userAuthenticatorService.verify(\n user.id,\n {\n kind: guessUserAuthenticatorKindByResponse(otp),\n response: otp,\n },\n {\n ipAddress: ctx.ipAddress ?? null,\n userAgent: ctx.userAgent ?? null,\n clientId: ctx.clientId,\n },\n );\n if (!verified) {\n throw new OAuth2MfaRequiredError({\n message: 'The provided second factor is not valid.',\n data: { kinds: status.kinds },\n });\n }\n\n return new Date().toISOString();\n }\n\n /**\n * Issue the MFA-pending ticket for factor kinds that cannot complete\n * inside the single grant POST (email needs a server-sent code,\n * WebAuthn an interactive ceremony). TOTP/recovery-only users keep\n * the inline `otp` fast-path and get no ticket — a pending session\n * per plain code entry would be pure churn.\n */\n protected async issueMfaTicket(\n user: User,\n kinds: `${UserAuthenticatorKind}`[],\n ctx: {\n ipAddress?: string,\n userAgent?: string,\n clientId: string | null,\n confirmation?: OAuth2TokenConfirmation,\n },\n ) : Promise<{ token: string, expiresIn: number } | null> {\n if (!this.mfaLoginService) {\n return null;\n }\n\n const interactive = kinds.includes(UserAuthenticatorKind.EMAIL) ||\n kinds.includes(UserAuthenticatorKind.WEBAUTHN);\n if (!interactive) {\n return null;\n }\n\n try {\n return await this.mfaLoginService.issueTicket(\n {\n user,\n clientId: ctx.clientId,\n confirmation: ctx.confirmation,\n },\n {\n ipAddress: ctx.ipAddress,\n userAgent: ctx.userAgent,\n },\n );\n } catch (e) {\n // degrade to a ticket-less mfa_required rather than letting a\n // transient issuance failure (pending-session write, cache,\n // signer) escape as a raw 500 from a controlled response path —\n // an otp-capable device can still complete, and the credential\n // retry re-attempts the ticket.\n this.logger?.warn('Issuing the MFA-pending login ticket failed.', { error: e });\n\n return null;\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"password.mjs","names":["EventName","EventScope","UserAuthenticatorKind","isEntityCredentialsInvalidError","isEntityInactiveError","OAuth2MfaRequiredError","OAuth2RequestError","OAuth2TokenGrant","readRequestBody","getRequestHeader","getRequestIP","PasswordGrantType","assertClientGrantAllowed","guessUserAuthenticatorKindByResponse","extractClientCredentialsFromRequest","extractOAuth2ClientCertificateEvidence","readRealmHint","readStringField","HTTPPasswordGrant","authenticator","clientAuthenticator","realmRepository","loginThrottleService","userAuthenticatorService","mfaLoginService","logger","certificateSource","ctx","runWithRequest","event","body","username","password","malformed","clientId","clientSecret","realm","resolve","certificateEvidence","client","authenticate","id","undefined","confirmation","resolveTokenBinding","PASSWORD","ipAddress","userAgent","identifier","trim","toLowerCase","assertNotThrottled","realmId","user","e","eventService","record","scope","OAUTH2","name","LOGIN_FAILED","actorType","actorId","actorName","requestIpAddress","requestUserAgent","requestPath","path","requestMethod","method","data","errorCode","code","metrics","recordLogin","mfaVerifiedAt","verifySecondFactor","runWith","status","challenge","issueMaterial","required","otp","ticket","issueMfaTicket","kinds","message","mfa_token","token","mfa_token_expires_in","expiresIn","verified","verify","kind","response","Date","toISOString","interactive","includes","EMAIL","WEBAUTHN","issueTicket","warn","error"],"sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/password.ts"],"sourcesContent":["/*\n * Copyright (c) 2025-2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { User } from '@authup/core-kit';\nimport { EventName, EventScope, UserAuthenticatorKind } from '@authup/core-kit';\nimport type { Logger } from '@authup/server-kit';\nimport { isEntityCredentialsInvalidError, isEntityInactiveError } from '@authup/errors';\nimport type { OAuth2TokenConfirmation, OAuth2TokenGrantResponse } from '@authup/specs';\nimport { OAuth2MfaRequiredError, OAuth2RequestError, OAuth2TokenGrant } from '@authup/specs';\nimport { readRequestBody } from '@routup/basic/body';\nimport type { IAppEvent } from 'routup';\nimport { getRequestHeader, getRequestIP } from 'routup';\nimport type {\n ICredentialsAuthenticator,\n ILoginThrottleService,\n IOAuth2MfaLoginService,\n IRealmRepository,\n IUserAuthenticatorService,\n OAuth2ClientAuthenticator,\n} from '../../../../../core/index.ts';\nimport {\n PasswordGrantType,\n assertClientGrantAllowed,\n guessUserAuthenticatorKindByResponse,\n} from '../../../../../core/index.ts';\nimport type { HTTPOAuth2PasswordGrantContext, IHTTPOAuth2Grant } from './types.ts';\nimport type { CertificateSource } from '../../../request/index.ts';\nimport {\n extractClientCredentialsFromRequest,\n extractOAuth2ClientCertificateEvidence,\n readRealmHint,\n readStringField,\n} from './utils/index.ts';\n\nexport class HTTPPasswordGrant extends PasswordGrantType implements IHTTPOAuth2Grant {\n protected authenticator : ICredentialsAuthenticator<User>;\n\n protected clientAuthenticator : OAuth2ClientAuthenticator;\n\n protected realmRepository : IRealmRepository;\n\n protected loginThrottleService? : ILoginThrottleService;\n\n protected userAuthenticatorService? : IUserAuthenticatorService;\n\n protected mfaLoginService? : IOAuth2MfaLoginService;\n\n protected logger? : Logger;\n\n protected certificateSource: CertificateSource;\n\n constructor(ctx: HTTPOAuth2PasswordGrantContext) {\n super(ctx);\n\n this.authenticator = ctx.authenticator;\n this.clientAuthenticator = ctx.clientAuthenticator;\n this.realmRepository = ctx.realmRepository;\n this.loginThrottleService = ctx.loginThrottleService;\n this.userAuthenticatorService = ctx.userAuthenticatorService;\n this.mfaLoginService = ctx.mfaLoginService;\n this.logger = ctx.logger;\n this.certificateSource = ctx.certificateSource ?? 'disabled';\n }\n\n async runWithRequest(event: IAppEvent): Promise<OAuth2TokenGrantResponse> {\n const body = await readRequestBody(event);\n\n const username = readStringField(body, 'username');\n const password = readStringField(body, 'password');\n if (!username || !password) {\n throw OAuth2RequestError.malformed('username and password must be provided.');\n }\n\n const { clientId, clientSecret } = await extractClientCredentialsFromRequest(event);\n\n const realm = await this.realmRepository.resolve(readRealmHint(body), true);\n const certificateEvidence = await extractOAuth2ClientCertificateEvidence(event, this.certificateSource);\n\n const client = clientId ?\n await this.clientAuthenticator.authenticate(\n clientId,\n clientSecret,\n realm.id,\n certificateEvidence,\n ) :\n undefined;\n\n const confirmation = client ?\n this.clientAuthenticator.resolveTokenBinding(client, certificateEvidence) :\n undefined;\n\n if (client) {\n assertClientGrantAllowed(client, OAuth2TokenGrant.PASSWORD);\n }\n\n const ipAddress = getRequestIP(event) ?? undefined;\n const userAgent = getRequestHeader(event, 'user-agent') ?? undefined;\n\n // canonical identifier form (layer 3) — the throttle key and the\n // loginFailed actorName must match what canonically stored rows carry.\n const identifier = username.trim().toLowerCase();\n\n await this.loginThrottleService?.assertNotThrottled({\n identifier,\n ipAddress,\n realmId: realm.id,\n });\n\n let user : User;\n try {\n user = await this.authenticator.authenticate(username, password, realm.id);\n } catch (e) {\n if (isEntityCredentialsInvalidError(e) || isEntityInactiveError(e)) {\n await this.eventService?.record({\n scope: EventScope.OAUTH2,\n name: EventName.LOGIN_FAILED,\n actorType: null,\n actorId: null,\n actorName: identifier,\n clientId: client?.id ?? null,\n realmId: realm.id,\n requestIpAddress: ipAddress ?? null,\n requestUserAgent: userAgent ?? null,\n requestPath: event.path,\n requestMethod: event.method,\n data: { errorCode: e.code },\n });\n this.metrics?.recordLogin('failure');\n }\n\n throw e;\n }\n\n const mfaVerifiedAt = await this.verifySecondFactor(user, body, {\n ipAddress,\n userAgent,\n clientId: client?.id ?? null,\n confirmation,\n });\n\n return this.runWith(\n {\n user, \n client, \n mfaVerifiedAt, \n },\n {\n confirmation,\n ipAddress,\n userAgent,\n },\n );\n }\n\n /**\n * MFA gate on the direct password grant: a user holding a confirmed\n * device must send a valid `otp` form parameter (TOTP or recovery\n * code, classified by shape) — otherwise `mfa_required`. Users\n * without a device pass through (they could never enroll otherwise).\n */\n protected async verifySecondFactor(\n user: User,\n body: Record<string, any>,\n ctx: {\n ipAddress?: string, \n userAgent?: string, \n clientId: string | null,\n confirmation?: OAuth2TokenConfirmation,\n },\n ): Promise<string | undefined> {\n if (!this.userAuthenticatorService) {\n return undefined;\n }\n\n // requirement flags + kinds only — no webauthn material on the token path.\n const status = await this.userAuthenticatorService.challenge(user.id, { issueMaterial: false });\n if (!status.required) {\n return undefined;\n }\n\n const otp = readStringField(body, 'otp');\n if (!otp) {\n // carry the challengeable kinds so a client (the hosted login form)\n // can tell whether a single-POST factor (totp/recovery) is on offer\n // or the user must complete an interactive challenge (email/webauthn).\n // For the interactive kinds an \"MFA-pending\" ticket (issue #3242)\n // rides along: a restricted mfa_token-kind bearer accepted ONLY by\n // the challenge routes, backed by a short-lived pending session\n // (mfa_at: null) — never a usable access/refresh pair.\n const ticket = await this.issueMfaTicket(user, status.kinds, ctx);\n\n throw new OAuth2MfaRequiredError({\n message: 'Complete a second-factor challenge to continue.',\n data: {\n kinds: status.kinds,\n ...(ticket ? {\n mfa_token: ticket.token,\n mfa_token_expires_in: ticket.expiresIn,\n } : {}),\n },\n });\n }\n\n const verified = await this.userAuthenticatorService.verify(\n user.id,\n {\n kind: guessUserAuthenticatorKindByResponse(otp),\n response: otp,\n },\n {\n ipAddress: ctx.ipAddress ?? null,\n userAgent: ctx.userAgent ?? null,\n clientId: ctx.clientId,\n },\n );\n if (!verified) {\n throw new OAuth2MfaRequiredError({\n message: 'The provided second factor is not valid.',\n data: { kinds: status.kinds },\n });\n }\n\n return new Date().toISOString();\n }\n\n /**\n * Issue the MFA-pending ticket for factor kinds that cannot complete\n * inside the single grant POST (email needs a server-sent code,\n * WebAuthn an interactive ceremony). TOTP/recovery-only users keep\n * the inline `otp` fast-path and get no ticket — a pending session\n * per plain code entry would be pure churn.\n */\n protected async issueMfaTicket(\n user: User,\n kinds: `${UserAuthenticatorKind}`[],\n ctx: {\n ipAddress?: string,\n userAgent?: string,\n clientId: string | null,\n confirmation?: OAuth2TokenConfirmation,\n },\n ) : Promise<{ token: string, expiresIn: number } | null> {\n if (!this.mfaLoginService) {\n return null;\n }\n\n const interactive = kinds.includes(UserAuthenticatorKind.EMAIL) ||\n kinds.includes(UserAuthenticatorKind.WEBAUTHN);\n if (!interactive) {\n return null;\n }\n\n try {\n return await this.mfaLoginService.issueTicket(\n {\n user,\n clientId: ctx.clientId,\n confirmation: ctx.confirmation,\n },\n {\n ipAddress: ctx.ipAddress,\n userAgent: ctx.userAgent,\n },\n );\n } catch (e) {\n // degrade to a ticket-less mfa_required rather than letting a\n // transient issuance failure (pending-session write, cache,\n // signer) escape as a raw 500 from a controlled response path —\n // an otp-capable device can still complete, and the credential\n // retry re-attempts the ticket.\n this.logger?.warn('Issuing the MFA-pending login ticket failed.', { error: e });\n\n return null;\n }\n }\n}\n"],"mappings":"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"}
@@ -49,7 +49,7 @@ var HTTPOAuth2RefreshTokenGrant = class extends OAuth2RefreshTokenGrant {
49
49
  if (client && isClientPublic(client) && payload.realm_id && payload.realm_id !== client.realmId) throw OAuth2GrantError.invalid();
50
50
  return this.runWith(payload, {
51
51
  confirmation,
52
- ipAddress: getRequestIP(event, { trustProxy: true }) ?? void 0,
52
+ ipAddress: getRequestIP(event) ?? void 0,
53
53
  userAgent: getRequestHeader(event, "user-agent") ?? void 0
54
54
  });
55
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"refresh_token.mjs","names":["isClientPublic","OAuth2GrantError","OAuth2RequestError","OAuth2TokenGrant","readRequestBody","getRequestHeader","getRequestIP","OAuth2RefreshTokenGrant","assertClientGrantAllowed","extractClientCredentialsFromRequest","extractOAuth2ClientCertificateEvidence","readRealmHint","HTTPOAuth2RefreshTokenGrant","clientAuthenticator","refreshTokenVerifier","realmRepository","certificateSource","ctx","tokenVerifier","runWithRequest","event","body","refreshToken","refresh_token","length","malformed","clientId","clientSecret","certificateEvidence","payload","verify","skipActiveCheck","client","realm","resolve","authenticate","id","client_id","invalid","undefined","REFRESH_TOKEN","confirmation","cnf","expectedThumbprint","validateCertificateEvidenceForBinding","resolveTokenBinding","realm_id","realmId","runWith","ipAddress","trustProxy","userAgent"],"sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/refresh_token.ts"],"sourcesContent":["/*\n * Copyright (c) 2025-2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { type Client, isClientPublic } from '@authup/core-kit';\nimport type { OAuth2TokenConfirmation, OAuth2TokenGrantResponse } from '@authup/specs';\nimport { OAuth2GrantError, OAuth2RequestError, OAuth2TokenGrant } from '@authup/specs';\nimport { readRequestBody } from '@routup/basic/body';\nimport type { IAppEvent } from 'routup';\nimport { getRequestHeader, getRequestIP } from 'routup';\nimport { OAuth2RefreshTokenGrant, assertClientGrantAllowed } from '../../../../../core/index.ts';\nimport type {\n IOAuth2TokenVerifier,\n IRealmRepository,\n OAuth2ClientAuthenticator,\n} from '../../../../../core/index.ts';\nimport type { HTTPOAuth2RefreshTokenGrantContext, IHTTPOAuth2Grant } from './types.ts';\nimport type { CertificateSource } from '../../../request/index.ts';\nimport {\n extractClientCredentialsFromRequest,\n extractOAuth2ClientCertificateEvidence,\n readRealmHint,\n} from './utils/index.ts';\n\nexport class HTTPOAuth2RefreshTokenGrant extends OAuth2RefreshTokenGrant implements IHTTPOAuth2Grant {\n protected clientAuthenticator : OAuth2ClientAuthenticator;\n\n protected refreshTokenVerifier : IOAuth2TokenVerifier;\n\n protected realmRepository : IRealmRepository;\n\n protected certificateSource: CertificateSource;\n\n constructor(ctx: HTTPOAuth2RefreshTokenGrantContext) {\n super(ctx);\n\n this.clientAuthenticator = ctx.clientAuthenticator;\n this.refreshTokenVerifier = ctx.tokenVerifier;\n this.realmRepository = ctx.realmRepository;\n this.certificateSource = ctx.certificateSource ?? 'disabled';\n }\n\n async runWithRequest(event: IAppEvent): Promise<OAuth2TokenGrantResponse> {\n const body = await readRequestBody(event);\n const refreshToken = body?.refresh_token;\n if (typeof refreshToken !== 'string' || refreshToken.length === 0) {\n throw OAuth2RequestError.malformed();\n }\n\n const { clientId, clientSecret } = await extractClientCredentialsFromRequest(event);\n const certificateEvidence = await extractOAuth2ClientCertificateEvidence(event, this.certificateSource);\n\n // RFC 6749 §6: verify the refresh token first to learn its bound\n // client (if any), then enforce binding. Authenticate the requesting\n // client when credentials are present, or when the token requires\n // a client binding.\n //\n // skipActiveCheck: the durable auth_session_tokens row (not the cache\n // blocklist) is the refresh-token authority, so a replayed/consumed\n // token must reach runWith() to trigger family revocation instead of\n // being rejected here with JWT_INACTIVE.\n const payload = await this.refreshTokenVerifier.verify(refreshToken, { skipActiveCheck: true });\n\n let client: Client | undefined;\n\n if (clientId) {\n // A client authenticated itself. Resolve by the presented\n // id/secret (name resolution scoped by the realm hint — resolved\n // lazily so a bare refresh skips the SELECT) and enforce the\n // token↔client binding.\n const realm = await this.realmRepository.resolve(readRealmHint(body), true);\n\n client = await this.clientAuthenticator.authenticate(\n clientId,\n clientSecret,\n realm.id,\n certificateEvidence,\n );\n\n if (payload.client_id && payload.client_id !== client.id) {\n throw OAuth2GrantError.invalid();\n }\n } else if (payload.client_id) {\n // No client credentials were presented, but the token is bound to\n // a client. RFC 6749 §10.4: a public client cannot authenticate\n // (no secret) and is not required to — the bound identity is read\n // from the signed token (client_id is server-minted, so trusted)\n // and refresh-token rotation/replay detection is the abuse control.\n // A client with an authentication method MUST still authenticate.\n // Supplying the server-minted client id lets TLS clients prove\n // themselves with the request certificate, while a secret client\n // still fails because its secret is absent.\n client = await this.clientAuthenticator.authenticate(\n payload.client_id,\n undefined,\n undefined,\n certificateEvidence,\n );\n }\n\n if (client) {\n assertClientGrantAllowed(client, OAuth2TokenGrant.REFRESH_TOKEN);\n }\n\n let confirmation: OAuth2TokenConfirmation | undefined;\n if (payload.cnf) {\n const expectedThumbprint = payload.cnf['x5t#S256'];\n if (typeof expectedThumbprint !== 'string' || expectedThumbprint.length === 0) {\n throw OAuth2GrantError.invalid();\n }\n\n confirmation = this.clientAuthenticator.validateCertificateEvidenceForBinding(\n certificateEvidence,\n );\n if (confirmation['x5t#S256'] !== expectedThumbprint) {\n throw OAuth2GrantError.invalid();\n }\n } else if (client) {\n confirmation = this.clientAuthenticator.resolveTokenBinding(client, certificateEvidence);\n }\n\n // Realm parity for PUBLIC clients only: a public client may not refresh\n // a token whose realm differs from the (bound) client's own realm.\n // Kills cross-realm refresh tokens minted for a public `web` client\n // before the authorize-side realm gate existed. Authenticated clients\n // are exempt — the configured secret/certificate proves identity, and the\n // documented cross-realm password grant (UUID-identified user against a\n // master-realm client) depends on that exemption.\n if (\n client &&\n isClientPublic(client) &&\n payload.realm_id &&\n payload.realm_id !== client.realmId\n ) {\n throw OAuth2GrantError.invalid();\n }\n\n return this.runWith(payload, {\n confirmation,\n ipAddress: getRequestIP(event, { trustProxy: true }) ?? undefined,\n userAgent: getRequestHeader(event, 'user-agent') ?? undefined,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AA2BA,IAAaY,8BAAb,cAAiDL,wBAAAA;CACnCM;CAEAC;CAEAC;CAEAC;CAEV,YAAYC,KAAyC;EACjD,MAAMA,GAAAA;EAEN,KAAKJ,sBAAsBI,IAAIJ;EAC/B,KAAKC,uBAAuBG,IAAIC;EAChC,KAAKH,kBAAkBE,IAAIF;EAC3B,KAAKC,oBAAoBC,IAAID,qBAAqB;CACtD;CAEA,MAAMG,eAAeC,OAAqD;EACtE,MAAMC,OAAO,MAAMjB,gBAAgBgB,KAAAA;EACnC,MAAME,eAAeD,MAAME;EAC3B,IAAI,OAAOD,iBAAiB,YAAYA,aAAaE,WAAW,GAC5D,MAAMtB,mBAAmBuB,UAAS;EAGtC,MAAM,EAAEC,UAAUC,iBAAiB,MAAMlB,oCAAoCW,KAAAA;EAC7E,MAAMQ,sBAAsB,MAAMlB,uCAAuCU,OAAO,KAAKJ,iBAAiB;EAWtG,MAAMa,UAAU,MAAM,KAAKf,qBAAqBgB,OAAOR,cAAc,EAAES,iBAAiB,KAAK,CAAA;EAE7F,IAAIC;EAEJ,IAAIN,UAAU;GAKV,MAAMO,QAAQ,MAAM,KAAKlB,gBAAgBmB,QAAQvB,cAAcU,IAAAA,GAAO,IAAA;GAEtEW,SAAS,MAAM,KAAKnB,oBAAoBsB,aACpCT,UACAC,cACAM,MAAMG,IACNR,mBAAAA;GAGJ,IAAIC,QAAQQ,aAAaR,QAAQQ,cAAcL,OAAOI,IAClD,MAAMnC,iBAAiBqC,QAAO;EAEtC,OAAO,IAAIT,QAAQQ,WAUfL,SAAS,MAAM,KAAKnB,oBAAoBsB,aACpCN,QAAQQ,WACRE,KAAAA,GACAA,KAAAA,GACAX,mBAAAA;EAIR,IAAII,QACAxB,yBAAyBwB,QAAQ7B,iBAAiBqC,aAAa;EAGnE,IAAIC;EACJ,IAAIZ,QAAQa,KAAK;GACb,MAAMC,qBAAqBd,QAAQa,IAAI;GACvC,IAAI,OAAOC,uBAAuB,YAAYA,mBAAmBnB,WAAW,GACxE,MAAMvB,iBAAiBqC,QAAO;GAGlCG,eAAe,KAAK5B,oBAAoB+B,sCACpChB,mBAAAA;GAEJ,IAAIa,aAAa,gBAAgBE,oBAC7B,MAAM1C,iBAAiBqC,QAAO;EAEtC,OAAO,IAAIN,QACPS,eAAe,KAAK5B,oBAAoBgC,oBAAoBb,QAAQJ,mBAAAA;EAUxE,IACII,UACAhC,eAAegC,MAAAA,KACfH,QAAQiB,YACRjB,QAAQiB,aAAad,OAAOe,SAE5B,MAAM9C,iBAAiBqC,QAAO;EAGlC,OAAO,KAAKU,QAAQnB,SAAS;GACzBY;GACAQ,WAAW3C,aAAac,OAAO,EAAE8B,YAAY,KAAK,CAAA,KAAMX,KAAAA;GACxDY,WAAW9C,iBAAiBe,OAAO,YAAA,KAAiBmB,KAAAA;EACxD,CAAA;CACJ;AACJ"}
1
+ {"version":3,"file":"refresh_token.mjs","names":["isClientPublic","OAuth2GrantError","OAuth2RequestError","OAuth2TokenGrant","readRequestBody","getRequestHeader","getRequestIP","OAuth2RefreshTokenGrant","assertClientGrantAllowed","extractClientCredentialsFromRequest","extractOAuth2ClientCertificateEvidence","readRealmHint","HTTPOAuth2RefreshTokenGrant","clientAuthenticator","refreshTokenVerifier","realmRepository","certificateSource","ctx","tokenVerifier","runWithRequest","event","body","refreshToken","refresh_token","length","malformed","clientId","clientSecret","certificateEvidence","payload","verify","skipActiveCheck","client","realm","resolve","authenticate","id","client_id","invalid","undefined","REFRESH_TOKEN","confirmation","cnf","expectedThumbprint","validateCertificateEvidenceForBinding","resolveTokenBinding","realm_id","realmId","runWith","ipAddress","userAgent"],"sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/refresh_token.ts"],"sourcesContent":["/*\n * Copyright (c) 2025-2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { type Client, isClientPublic } from '@authup/core-kit';\nimport type { OAuth2TokenConfirmation, OAuth2TokenGrantResponse } from '@authup/specs';\nimport { OAuth2GrantError, OAuth2RequestError, OAuth2TokenGrant } from '@authup/specs';\nimport { readRequestBody } from '@routup/basic/body';\nimport type { IAppEvent } from 'routup';\nimport { getRequestHeader, getRequestIP } from 'routup';\nimport { OAuth2RefreshTokenGrant, assertClientGrantAllowed } from '../../../../../core/index.ts';\nimport type {\n IOAuth2TokenVerifier,\n IRealmRepository,\n OAuth2ClientAuthenticator,\n} from '../../../../../core/index.ts';\nimport type { HTTPOAuth2RefreshTokenGrantContext, IHTTPOAuth2Grant } from './types.ts';\nimport type { CertificateSource } from '../../../request/index.ts';\nimport {\n extractClientCredentialsFromRequest,\n extractOAuth2ClientCertificateEvidence,\n readRealmHint,\n} from './utils/index.ts';\n\nexport class HTTPOAuth2RefreshTokenGrant extends OAuth2RefreshTokenGrant implements IHTTPOAuth2Grant {\n protected clientAuthenticator : OAuth2ClientAuthenticator;\n\n protected refreshTokenVerifier : IOAuth2TokenVerifier;\n\n protected realmRepository : IRealmRepository;\n\n protected certificateSource: CertificateSource;\n\n constructor(ctx: HTTPOAuth2RefreshTokenGrantContext) {\n super(ctx);\n\n this.clientAuthenticator = ctx.clientAuthenticator;\n this.refreshTokenVerifier = ctx.tokenVerifier;\n this.realmRepository = ctx.realmRepository;\n this.certificateSource = ctx.certificateSource ?? 'disabled';\n }\n\n async runWithRequest(event: IAppEvent): Promise<OAuth2TokenGrantResponse> {\n const body = await readRequestBody(event);\n const refreshToken = body?.refresh_token;\n if (typeof refreshToken !== 'string' || refreshToken.length === 0) {\n throw OAuth2RequestError.malformed();\n }\n\n const { clientId, clientSecret } = await extractClientCredentialsFromRequest(event);\n const certificateEvidence = await extractOAuth2ClientCertificateEvidence(event, this.certificateSource);\n\n // RFC 6749 §6: verify the refresh token first to learn its bound\n // client (if any), then enforce binding. Authenticate the requesting\n // client when credentials are present, or when the token requires\n // a client binding.\n //\n // skipActiveCheck: the durable auth_session_tokens row (not the cache\n // blocklist) is the refresh-token authority, so a replayed/consumed\n // token must reach runWith() to trigger family revocation instead of\n // being rejected here with JWT_INACTIVE.\n const payload = await this.refreshTokenVerifier.verify(refreshToken, { skipActiveCheck: true });\n\n let client: Client | undefined;\n\n if (clientId) {\n // A client authenticated itself. Resolve by the presented\n // id/secret (name resolution scoped by the realm hint — resolved\n // lazily so a bare refresh skips the SELECT) and enforce the\n // token↔client binding.\n const realm = await this.realmRepository.resolve(readRealmHint(body), true);\n\n client = await this.clientAuthenticator.authenticate(\n clientId,\n clientSecret,\n realm.id,\n certificateEvidence,\n );\n\n if (payload.client_id && payload.client_id !== client.id) {\n throw OAuth2GrantError.invalid();\n }\n } else if (payload.client_id) {\n // No client credentials were presented, but the token is bound to\n // a client. RFC 6749 §10.4: a public client cannot authenticate\n // (no secret) and is not required to — the bound identity is read\n // from the signed token (client_id is server-minted, so trusted)\n // and refresh-token rotation/replay detection is the abuse control.\n // A client with an authentication method MUST still authenticate.\n // Supplying the server-minted client id lets TLS clients prove\n // themselves with the request certificate, while a secret client\n // still fails because its secret is absent.\n client = await this.clientAuthenticator.authenticate(\n payload.client_id,\n undefined,\n undefined,\n certificateEvidence,\n );\n }\n\n if (client) {\n assertClientGrantAllowed(client, OAuth2TokenGrant.REFRESH_TOKEN);\n }\n\n let confirmation: OAuth2TokenConfirmation | undefined;\n if (payload.cnf) {\n const expectedThumbprint = payload.cnf['x5t#S256'];\n if (typeof expectedThumbprint !== 'string' || expectedThumbprint.length === 0) {\n throw OAuth2GrantError.invalid();\n }\n\n confirmation = this.clientAuthenticator.validateCertificateEvidenceForBinding(\n certificateEvidence,\n );\n if (confirmation['x5t#S256'] !== expectedThumbprint) {\n throw OAuth2GrantError.invalid();\n }\n } else if (client) {\n confirmation = this.clientAuthenticator.resolveTokenBinding(client, certificateEvidence);\n }\n\n // Realm parity for PUBLIC clients only: a public client may not refresh\n // a token whose realm differs from the (bound) client's own realm.\n // Kills cross-realm refresh tokens minted for a public `web` client\n // before the authorize-side realm gate existed. Authenticated clients\n // are exempt — the configured secret/certificate proves identity, and the\n // documented cross-realm password grant (UUID-identified user against a\n // master-realm client) depends on that exemption.\n if (\n client &&\n isClientPublic(client) &&\n payload.realm_id &&\n payload.realm_id !== client.realmId\n ) {\n throw OAuth2GrantError.invalid();\n }\n\n return this.runWith(payload, {\n confirmation,\n ipAddress: getRequestIP(event) ?? undefined,\n userAgent: getRequestHeader(event, 'user-agent') ?? undefined,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AA2BA,IAAaY,8BAAb,cAAiDL,wBAAAA;CACnCM;CAEAC;CAEAC;CAEAC;CAEV,YAAYC,KAAyC;EACjD,MAAMA,GAAAA;EAEN,KAAKJ,sBAAsBI,IAAIJ;EAC/B,KAAKC,uBAAuBG,IAAIC;EAChC,KAAKH,kBAAkBE,IAAIF;EAC3B,KAAKC,oBAAoBC,IAAID,qBAAqB;CACtD;CAEA,MAAMG,eAAeC,OAAqD;EACtE,MAAMC,OAAO,MAAMjB,gBAAgBgB,KAAAA;EACnC,MAAME,eAAeD,MAAME;EAC3B,IAAI,OAAOD,iBAAiB,YAAYA,aAAaE,WAAW,GAC5D,MAAMtB,mBAAmBuB,UAAS;EAGtC,MAAM,EAAEC,UAAUC,iBAAiB,MAAMlB,oCAAoCW,KAAAA;EAC7E,MAAMQ,sBAAsB,MAAMlB,uCAAuCU,OAAO,KAAKJ,iBAAiB;EAWtG,MAAMa,UAAU,MAAM,KAAKf,qBAAqBgB,OAAOR,cAAc,EAAES,iBAAiB,KAAK,CAAA;EAE7F,IAAIC;EAEJ,IAAIN,UAAU;GAKV,MAAMO,QAAQ,MAAM,KAAKlB,gBAAgBmB,QAAQvB,cAAcU,IAAAA,GAAO,IAAA;GAEtEW,SAAS,MAAM,KAAKnB,oBAAoBsB,aACpCT,UACAC,cACAM,MAAMG,IACNR,mBAAAA;GAGJ,IAAIC,QAAQQ,aAAaR,QAAQQ,cAAcL,OAAOI,IAClD,MAAMnC,iBAAiBqC,QAAO;EAEtC,OAAO,IAAIT,QAAQQ,WAUfL,SAAS,MAAM,KAAKnB,oBAAoBsB,aACpCN,QAAQQ,WACRE,KAAAA,GACAA,KAAAA,GACAX,mBAAAA;EAIR,IAAII,QACAxB,yBAAyBwB,QAAQ7B,iBAAiBqC,aAAa;EAGnE,IAAIC;EACJ,IAAIZ,QAAQa,KAAK;GACb,MAAMC,qBAAqBd,QAAQa,IAAI;GACvC,IAAI,OAAOC,uBAAuB,YAAYA,mBAAmBnB,WAAW,GACxE,MAAMvB,iBAAiBqC,QAAO;GAGlCG,eAAe,KAAK5B,oBAAoB+B,sCACpChB,mBAAAA;GAEJ,IAAIa,aAAa,gBAAgBE,oBAC7B,MAAM1C,iBAAiBqC,QAAO;EAEtC,OAAO,IAAIN,QACPS,eAAe,KAAK5B,oBAAoBgC,oBAAoBb,QAAQJ,mBAAAA;EAUxE,IACII,UACAhC,eAAegC,MAAAA,KACfH,QAAQiB,YACRjB,QAAQiB,aAAad,OAAOe,SAE5B,MAAM9C,iBAAiBqC,QAAO;EAGlC,OAAO,KAAKU,QAAQnB,SAAS;GACzBY;GACAQ,WAAW3C,aAAac,KAAAA,KAAUmB,KAAAA;GAClCW,WAAW7C,iBAAiBe,OAAO,YAAA,KAAiBmB,KAAAA;EACxD,CAAA;CACJ;AACJ"}
@@ -1,6 +1,6 @@
1
1
  import type { Client } from '@authup/core-kit';
2
2
  import type { IAppEvent } from 'routup';
3
- import type { ClientCreatePayload, ClientSavePayload, ClientUpdatePayload, EntityCollectionResponse } from '@authup/core-http-kit';
3
+ import type { ClientCreatePayload, ClientSavePayload, ClientUpdatePayload, EntityCollectionResponse, EntityRecordResponse } from '@authup/core-http-kit';
4
4
  import type { IClientRepository, IClientService } from '../../../../../core/index.ts';
5
5
  export type ClientControllerContext = {
6
6
  service: IClientService;
@@ -11,10 +11,10 @@ export declare class ClientController {
11
11
  protected repository: IClientRepository;
12
12
  constructor(ctx: ClientControllerContext);
13
13
  getMany(event: IAppEvent): Promise<EntityCollectionResponse<Client>>;
14
- get(id: string, event: IAppEvent): Promise<Client>;
15
- add(data: ClientCreatePayload, event: IAppEvent): Promise<Client>;
16
- edit(id: string, data: ClientUpdatePayload, event: IAppEvent): Promise<Client>;
17
- put(id: string, data: ClientSavePayload, event: IAppEvent): Promise<Client>;
18
- drop(id: string, event: IAppEvent): Promise<Client>;
14
+ get(id: string, event: IAppEvent): Promise<EntityRecordResponse<Client>>;
15
+ add(data: ClientCreatePayload, event: IAppEvent): Promise<EntityRecordResponse<Client>>;
16
+ edit(id: string, data: ClientUpdatePayload, event: IAppEvent): Promise<EntityRecordResponse<Client>>;
17
+ put(id: string, data: ClientSavePayload, event: IAppEvent): Promise<EntityRecordResponse<Client>>;
18
+ drop(id: string, event: IAppEvent): Promise<EntityRecordResponse<Client>>;
19
19
  }
20
20
  //# sourceMappingURL=module.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/controllers/entities/client/module.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,KAAK,EACR,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAWtF,MAAM,MAAM,uBAAuB,GAAG;IAClC,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,iBAAiB,CAAC;CACjC,CAAC;AAEF,qBAEa,gBAAgB;IACzB,SAAS,CAAC,OAAO,EAAE,cAAc,CAAC;IAElC,SAAS,CAAC,UAAU,EAAE,iBAAiB,CAAC;gBAE5B,GAAG,EAAE,uBAAuB;IAMlC,OAAO,CACG,KAAK,EAAE,SAAS,GAC7B,OAAO,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;IActC,GAAG,CACQ,EAAE,EAAE,MAAM,EACX,KAAK,EAAE,SAAS,GAC7B,OAAO,CAAC,MAAM,CAAC;IAiDZ,GAAG,CACI,IAAI,EAAE,mBAAmB,EACtB,KAAK,EAAE,SAAS,GAC7B,OAAO,CAAC,MAAM,CAAC;IAWZ,IAAI,CACO,EAAE,EAAE,MAAM,EACd,IAAI,EAAE,mBAAmB,EACtB,KAAK,EAAE,SAAS,GAC7B,OAAO,CAAC,MAAM,CAAC;IAWZ,GAAG,CACQ,EAAE,EAAE,MAAM,EACd,IAAI,EAAE,iBAAiB,EACpB,KAAK,EAAE,SAAS,GAC7B,OAAO,CAAC,MAAM,CAAC;IAiBZ,IAAI,CACO,EAAE,EAAE,MAAM,EACX,KAAK,EAAE,SAAS,GAC7B,OAAO,CAAC,MAAM,CAAC;CAQrB"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/controllers/entities/client/module.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,KAAK,EACR,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,oBAAoB,EACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAgBtF,MAAM,MAAM,uBAAuB,GAAG;IAClC,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,iBAAiB,CAAC;CACjC,CAAC;AAEF,qBAEa,gBAAgB;IACzB,SAAS,CAAC,OAAO,EAAE,cAAc,CAAC;IAElC,SAAS,CAAC,UAAU,EAAE,iBAAiB,CAAC;gBAE5B,GAAG,EAAE,uBAAuB;IAMlC,OAAO,CACG,KAAK,EAAE,SAAS,GAC7B,OAAO,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAiBtC,GAAG,CACQ,EAAE,EAAE,MAAM,EACX,KAAK,EAAE,SAAS,GAC7B,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAiDlC,GAAG,CACI,IAAI,EAAE,mBAAmB,EACtB,KAAK,EAAE,SAAS,GAC7B,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAWlC,IAAI,CACO,EAAE,EAAE,MAAM,EACd,IAAI,EAAE,mBAAmB,EACtB,KAAK,EAAE,SAAS,GAC7B,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAWlC,GAAG,CACQ,EAAE,EAAE,MAAM,EACd,IAAI,EAAE,iBAAiB,EACpB,KAAK,EAAE,SAAS,GAC7B,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAiBlC,IAAI,CACO,EAAE,EAAE,MAAM,EACX,KAAK,EAAE,SAAS,GAC7B,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;CAQ3C"}