@authup/server-core 1.0.0-beta.52 → 1.0.0-beta.53

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 (742) hide show
  1. package/dist/adapters/database/data-source/options/module.d.ts.map +1 -1
  2. package/dist/adapters/database/data-source/options/module.mjs +18 -8
  3. package/dist/adapters/database/data-source/options/module.mjs.map +1 -1
  4. package/dist/adapters/database/domains/client/entity.d.ts +5 -2
  5. package/dist/adapters/database/domains/client/entity.d.ts.map +1 -1
  6. package/dist/adapters/database/domains/client/entity.mjs +28 -4
  7. package/dist/adapters/database/domains/client/entity.mjs.map +1 -1
  8. package/dist/adapters/database/domains/client-permission/entity.mjs +2 -2
  9. package/dist/adapters/database/domains/consent/entity.d.ts +20 -0
  10. package/dist/adapters/database/domains/consent/entity.d.ts.map +1 -0
  11. package/dist/adapters/database/domains/consent/entity.mjs +110 -0
  12. package/dist/adapters/database/domains/consent/entity.mjs.map +1 -0
  13. package/dist/adapters/database/domains/consent/index.d.ts +3 -0
  14. package/dist/adapters/database/domains/consent/index.d.ts.map +1 -0
  15. package/dist/adapters/database/domains/consent/index.mjs +6 -0
  16. package/dist/adapters/database/domains/consent/subscriber.d.ts +6 -0
  17. package/dist/adapters/database/domains/consent/subscriber.d.ts.map +1 -0
  18. package/dist/adapters/database/domains/consent/subscriber.mjs +45 -0
  19. package/dist/adapters/database/domains/consent/subscriber.mjs.map +1 -0
  20. package/dist/adapters/database/domains/constants.d.ts +1 -0
  21. package/dist/adapters/database/domains/constants.d.ts.map +1 -1
  22. package/dist/adapters/database/domains/constants.mjs +1 -0
  23. package/dist/adapters/database/domains/constants.mjs.map +1 -1
  24. package/dist/adapters/database/domains/event/entity.d.ts +22 -0
  25. package/dist/adapters/database/domains/event/entity.d.ts.map +1 -0
  26. package/dist/adapters/database/domains/event/entity.mjs +174 -0
  27. package/dist/adapters/database/domains/event/entity.mjs.map +1 -0
  28. package/dist/adapters/database/domains/event/index.d.ts +2 -0
  29. package/dist/adapters/database/domains/event/index.d.ts.map +1 -0
  30. package/dist/adapters/database/domains/event/index.mjs +5 -0
  31. package/dist/adapters/database/domains/identity-provider-account/entity.mjs +2 -2
  32. package/dist/adapters/database/domains/index.d.ts +4 -0
  33. package/dist/adapters/database/domains/index.d.ts.map +1 -1
  34. package/dist/adapters/database/domains/index.mjs +24 -15
  35. package/dist/adapters/database/domains/key/entity.d.ts +7 -3
  36. package/dist/adapters/database/domains/key/entity.d.ts.map +1 -1
  37. package/dist/adapters/database/domains/key/entity.mjs +35 -10
  38. package/dist/adapters/database/domains/key/entity.mjs.map +1 -1
  39. package/dist/adapters/database/domains/permission-policy/entity.mjs +2 -2
  40. package/dist/adapters/database/domains/policy/repository.d.ts.map +1 -1
  41. package/dist/adapters/database/domains/policy/repository.mjs +3 -3
  42. package/dist/adapters/database/domains/policy/repository.mjs.map +1 -1
  43. package/dist/adapters/database/domains/robot-permission/entity.mjs +2 -2
  44. package/dist/adapters/database/domains/role/repository.mjs +1 -1
  45. package/dist/adapters/database/domains/role-permission/entity.mjs +2 -2
  46. package/dist/adapters/database/domains/session/entity.d.ts +3 -1
  47. package/dist/adapters/database/domains/session/entity.d.ts.map +1 -1
  48. package/dist/adapters/database/domains/session/entity.mjs +12 -0
  49. package/dist/adapters/database/domains/session/entity.mjs.map +1 -1
  50. package/dist/adapters/database/domains/trust-anchor/entity.d.ts +13 -0
  51. package/dist/adapters/database/domains/trust-anchor/entity.d.ts.map +1 -0
  52. package/dist/adapters/database/domains/trust-anchor/entity.mjs +55 -0
  53. package/dist/adapters/database/domains/trust-anchor/entity.mjs.map +1 -0
  54. package/dist/adapters/database/domains/trust-anchor/index.d.ts +2 -0
  55. package/dist/adapters/database/domains/trust-anchor/index.d.ts.map +1 -0
  56. package/dist/adapters/database/domains/trust-anchor/index.mjs +5 -0
  57. package/dist/adapters/database/domains/user-authenticator/entity.d.ts +20 -0
  58. package/dist/adapters/database/domains/user-authenticator/entity.d.ts.map +1 -0
  59. package/dist/adapters/database/domains/user-authenticator/entity.mjs +98 -0
  60. package/dist/adapters/database/domains/user-authenticator/entity.mjs.map +1 -0
  61. package/dist/adapters/database/domains/user-authenticator/index.d.ts +2 -0
  62. package/dist/adapters/database/domains/user-authenticator/index.d.ts.map +1 -0
  63. package/dist/adapters/database/domains/user-authenticator/index.mjs +5 -0
  64. package/dist/adapters/database/domains/user-permission/entity.mjs +1 -1
  65. package/dist/adapters/database/errors/driver.d.ts +14 -0
  66. package/dist/adapters/database/errors/driver.d.ts.map +1 -0
  67. package/dist/adapters/database/errors/driver.mjs +32 -0
  68. package/dist/adapters/database/errors/driver.mjs.map +1 -0
  69. package/dist/adapters/database/errors/index.d.ts +1 -0
  70. package/dist/adapters/database/errors/index.d.ts.map +1 -1
  71. package/dist/adapters/database/errors/index.mjs +2 -1
  72. package/dist/adapters/database/index.mjs +17 -11
  73. package/dist/adapters/database/migrations/mysql/1783769340000-Default.d.ts +50 -0
  74. package/dist/adapters/database/migrations/mysql/1783769340000-Default.d.ts.map +1 -0
  75. package/dist/adapters/database/migrations/mysql/1783769340000-Default.mjs +320 -0
  76. package/dist/adapters/database/migrations/mysql/1783769340000-Default.mjs.map +1 -0
  77. package/dist/adapters/database/migrations/postgres/1783769340000-Default.d.ts +50 -0
  78. package/dist/adapters/database/migrations/postgres/1783769340000-Default.d.ts.map +1 -0
  79. package/dist/adapters/database/migrations/postgres/1783769340000-Default.mjs +310 -0
  80. package/dist/adapters/database/migrations/postgres/1783769340000-Default.mjs.map +1 -0
  81. package/dist/adapters/database/subscriber/module.d.ts +1 -1
  82. package/dist/adapters/database/subscriber/module.d.ts.map +1 -1
  83. package/dist/adapters/database/subscriber/module.mjs +4 -3
  84. package/dist/adapters/database/subscriber/module.mjs.map +1 -1
  85. package/dist/adapters/http/adapters/index.mjs +2 -1
  86. package/dist/adapters/http/adapters/oauth2/authorization/module.d.ts +4 -1
  87. package/dist/adapters/http/adapters/oauth2/authorization/module.d.ts.map +1 -1
  88. package/dist/adapters/http/adapters/oauth2/authorization/module.mjs +27 -2
  89. package/dist/adapters/http/adapters/oauth2/authorization/module.mjs.map +1 -1
  90. package/dist/adapters/http/adapters/oauth2/authorization/types.d.ts +9 -1
  91. package/dist/adapters/http/adapters/oauth2/authorization/types.d.ts.map +1 -1
  92. package/dist/adapters/http/adapters/oauth2/grant-types/authorize.d.ts +4 -1
  93. package/dist/adapters/http/adapters/oauth2/grant-types/authorize.d.ts.map +1 -1
  94. package/dist/adapters/http/adapters/oauth2/grant-types/authorize.mjs +23 -3
  95. package/dist/adapters/http/adapters/oauth2/grant-types/authorize.mjs.map +1 -1
  96. package/dist/adapters/http/adapters/oauth2/grant-types/client-credentials.d.ts +4 -3
  97. package/dist/adapters/http/adapters/oauth2/grant-types/client-credentials.d.ts.map +1 -1
  98. package/dist/adapters/http/adapters/oauth2/grant-types/client-credentials.mjs +13 -6
  99. package/dist/adapters/http/adapters/oauth2/grant-types/client-credentials.mjs.map +1 -1
  100. package/dist/adapters/http/adapters/oauth2/grant-types/index.mjs +2 -1
  101. package/dist/adapters/http/adapters/oauth2/grant-types/password.d.ts +38 -2
  102. package/dist/adapters/http/adapters/oauth2/grant-types/password.d.ts.map +1 -1
  103. package/dist/adapters/http/adapters/oauth2/grant-types/password.mjs +119 -6
  104. package/dist/adapters/http/adapters/oauth2/grant-types/password.mjs.map +1 -1
  105. package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.d.ts +2 -0
  106. package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.d.ts.map +1 -1
  107. package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.mjs +16 -3
  108. package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.mjs.map +1 -1
  109. package/dist/adapters/http/adapters/oauth2/grant-types/types.d.ts +14 -3
  110. package/dist/adapters/http/adapters/oauth2/grant-types/types.d.ts.map +1 -1
  111. package/dist/adapters/http/adapters/oauth2/grant-types/utils/certificate.d.ts +5 -0
  112. package/dist/adapters/http/adapters/oauth2/grant-types/utils/certificate.d.ts.map +1 -0
  113. package/dist/adapters/http/adapters/oauth2/grant-types/utils/certificate.mjs +18 -0
  114. package/dist/adapters/http/adapters/oauth2/grant-types/utils/certificate.mjs.map +1 -0
  115. package/dist/adapters/http/adapters/oauth2/grant-types/utils/credentials.mjs +1 -1
  116. package/dist/adapters/http/adapters/oauth2/grant-types/utils/guess.mjs +1 -1
  117. package/dist/adapters/http/adapters/oauth2/grant-types/utils/index.d.ts +1 -0
  118. package/dist/adapters/http/adapters/oauth2/grant-types/utils/index.d.ts.map +1 -1
  119. package/dist/adapters/http/adapters/oauth2/grant-types/utils/index.mjs +2 -1
  120. package/dist/adapters/http/adapters/oauth2/index.mjs +2 -1
  121. package/dist/adapters/http/controllers/entities/consent/index.d.ts +2 -0
  122. package/dist/adapters/http/controllers/entities/consent/index.d.ts.map +1 -0
  123. package/dist/adapters/http/controllers/entities/consent/index.mjs +5 -0
  124. package/dist/adapters/http/controllers/entities/consent/module.d.ts +15 -0
  125. package/dist/adapters/http/controllers/entities/consent/module.d.ts.map +1 -0
  126. package/dist/adapters/http/controllers/entities/consent/module.mjs +82 -0
  127. package/dist/adapters/http/controllers/entities/consent/module.mjs.map +1 -0
  128. package/dist/adapters/http/controllers/entities/event/index.d.ts +2 -0
  129. package/dist/adapters/http/controllers/entities/event/index.d.ts.map +1 -0
  130. package/dist/adapters/http/controllers/entities/event/index.mjs +5 -0
  131. package/dist/adapters/http/controllers/entities/event/module.d.ts +14 -0
  132. package/dist/adapters/http/controllers/entities/event/module.d.ts.map +1 -0
  133. package/dist/adapters/http/controllers/entities/event/module.mjs +68 -0
  134. package/dist/adapters/http/controllers/entities/event/module.mjs.map +1 -0
  135. package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts +4 -1
  136. package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts.map +1 -1
  137. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs +38 -10
  138. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs.map +1 -1
  139. package/dist/adapters/http/controllers/entities/identity-provider/types.d.ts +3 -1
  140. package/dist/adapters/http/controllers/entities/identity-provider/types.d.ts.map +1 -1
  141. package/dist/adapters/http/controllers/entities/index.d.ts +5 -0
  142. package/dist/adapters/http/controllers/entities/index.d.ts.map +1 -1
  143. package/dist/adapters/http/controllers/entities/index.mjs +11 -1
  144. package/dist/adapters/http/controllers/entities/key/index.d.ts +2 -0
  145. package/dist/adapters/http/controllers/entities/key/index.d.ts.map +1 -0
  146. package/dist/adapters/http/controllers/entities/key/index.mjs +5 -0
  147. package/dist/adapters/http/controllers/entities/key/module.d.ts +17 -0
  148. package/dist/adapters/http/controllers/entities/key/module.d.ts.map +1 -0
  149. package/dist/adapters/http/controllers/entities/key/module.mjs +122 -0
  150. package/dist/adapters/http/controllers/entities/key/module.mjs.map +1 -0
  151. package/dist/adapters/http/controllers/entities/policy/utils/validation.mjs +1 -1
  152. package/dist/adapters/http/controllers/entities/realm/module.d.ts +2 -0
  153. package/dist/adapters/http/controllers/entities/realm/module.d.ts.map +1 -1
  154. package/dist/adapters/http/controllers/entities/realm/module.mjs +16 -1
  155. package/dist/adapters/http/controllers/entities/realm/module.mjs.map +1 -1
  156. package/dist/adapters/http/controllers/entities/trust-anchor/index.d.ts +2 -0
  157. package/dist/adapters/http/controllers/entities/trust-anchor/index.d.ts.map +1 -0
  158. package/dist/adapters/http/controllers/entities/trust-anchor/index.mjs +5 -0
  159. package/dist/adapters/http/controllers/entities/trust-anchor/module.d.ts +17 -0
  160. package/dist/adapters/http/controllers/entities/trust-anchor/module.d.ts.map +1 -0
  161. package/dist/adapters/http/controllers/entities/trust-anchor/module.mjs +120 -0
  162. package/dist/adapters/http/controllers/entities/trust-anchor/module.mjs.map +1 -0
  163. package/dist/adapters/http/controllers/entities/user-authenticator/index.d.ts +2 -0
  164. package/dist/adapters/http/controllers/entities/user-authenticator/index.d.ts.map +1 -0
  165. package/dist/adapters/http/controllers/entities/user-authenticator/index.mjs +5 -0
  166. package/dist/adapters/http/controllers/entities/user-authenticator/module.d.ts +21 -0
  167. package/dist/adapters/http/controllers/entities/user-authenticator/module.d.ts.map +1 -0
  168. package/dist/adapters/http/controllers/entities/user-authenticator/module.mjs +154 -0
  169. package/dist/adapters/http/controllers/entities/user-authenticator/module.mjs.map +1 -0
  170. package/dist/adapters/http/controllers/index.mjs +7 -1
  171. package/dist/adapters/http/controllers/workflows/authenticator-challenge/index.d.ts +2 -0
  172. package/dist/adapters/http/controllers/workflows/authenticator-challenge/index.d.ts.map +1 -0
  173. package/dist/adapters/http/controllers/workflows/authenticator-challenge/index.mjs +5 -0
  174. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.d.ts +46 -0
  175. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.d.ts.map +1 -0
  176. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.mjs +132 -0
  177. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.mjs.map +1 -0
  178. package/dist/adapters/http/controllers/workflows/authorize/module.d.ts.map +1 -1
  179. package/dist/adapters/http/controllers/workflows/authorize/module.mjs +34 -6
  180. package/dist/adapters/http/controllers/workflows/authorize/module.mjs.map +1 -1
  181. package/dist/adapters/http/controllers/workflows/authorize/types.d.ts +17 -1
  182. package/dist/adapters/http/controllers/workflows/authorize/types.d.ts.map +1 -1
  183. package/dist/adapters/http/controllers/workflows/index.d.ts +1 -0
  184. package/dist/adapters/http/controllers/workflows/index.d.ts.map +1 -1
  185. package/dist/adapters/http/controllers/workflows/index.mjs +3 -1
  186. package/dist/adapters/http/controllers/workflows/jwks/handlers/read.d.ts.map +1 -1
  187. package/dist/adapters/http/controllers/workflows/jwks/handlers/read.mjs +28 -14
  188. package/dist/adapters/http/controllers/workflows/jwks/handlers/read.mjs.map +1 -1
  189. package/dist/adapters/http/controllers/workflows/jwks/module.d.ts.map +1 -1
  190. package/dist/adapters/http/controllers/workflows/jwks/module.mjs +28 -14
  191. package/dist/adapters/http/controllers/workflows/jwks/module.mjs.map +1 -1
  192. package/dist/adapters/http/controllers/workflows/token/module.d.ts +2 -1
  193. package/dist/adapters/http/controllers/workflows/token/module.d.ts.map +1 -1
  194. package/dist/adapters/http/controllers/workflows/token/module.mjs +28 -8
  195. package/dist/adapters/http/controllers/workflows/token/module.mjs.map +1 -1
  196. package/dist/adapters/http/controllers/workflows/token/types.d.ts +11 -4
  197. package/dist/adapters/http/controllers/workflows/token/types.d.ts.map +1 -1
  198. package/dist/adapters/http/index.mjs +13 -3
  199. package/dist/adapters/http/middleware/built-in/assets.mjs +1 -1
  200. package/dist/adapters/http/middleware/built-in/authorization/module.d.ts +13 -0
  201. package/dist/adapters/http/middleware/built-in/authorization/module.d.ts.map +1 -1
  202. package/dist/adapters/http/middleware/built-in/authorization/module.mjs +52 -2
  203. package/dist/adapters/http/middleware/built-in/authorization/module.mjs.map +1 -1
  204. package/dist/adapters/http/middleware/built-in/authorization/types.d.ts +2 -0
  205. package/dist/adapters/http/middleware/built-in/authorization/types.d.ts.map +1 -1
  206. package/dist/adapters/http/middleware/built-in/index.mjs +2 -2
  207. package/dist/adapters/http/middleware/built-in/prometheus.d.ts +12 -1
  208. package/dist/adapters/http/middleware/built-in/prometheus.d.ts.map +1 -1
  209. package/dist/adapters/http/middleware/built-in/prometheus.mjs +75 -6
  210. package/dist/adapters/http/middleware/built-in/prometheus.mjs.map +1 -1
  211. package/dist/adapters/http/middleware/index.mjs +2 -2
  212. package/dist/adapters/http/request/client-certificate.d.ts +5 -0
  213. package/dist/adapters/http/request/client-certificate.d.ts.map +1 -0
  214. package/dist/adapters/http/request/client-certificate.mjs +88 -0
  215. package/dist/adapters/http/request/client-certificate.mjs.map +1 -0
  216. package/dist/adapters/http/request/constants.d.ts +1 -0
  217. package/dist/adapters/http/request/constants.d.ts.map +1 -1
  218. package/dist/adapters/http/request/constants.mjs +6 -1
  219. package/dist/adapters/http/request/constants.mjs.map +1 -1
  220. package/dist/adapters/http/request/event-context.d.ts +19 -0
  221. package/dist/adapters/http/request/event-context.d.ts.map +1 -0
  222. package/dist/adapters/http/request/event-context.mjs +37 -0
  223. package/dist/adapters/http/request/event-context.mjs.map +1 -0
  224. package/dist/adapters/http/request/helpers/index.d.ts +1 -0
  225. package/dist/adapters/http/request/helpers/index.d.ts.map +1 -1
  226. package/dist/adapters/http/request/helpers/index.mjs +2 -1
  227. package/dist/adapters/http/request/helpers/mfa-login-ticket.d.ts +16 -0
  228. package/dist/adapters/http/request/helpers/mfa-login-ticket.d.ts.map +1 -0
  229. package/dist/adapters/http/request/helpers/mfa-login-ticket.mjs +15 -0
  230. package/dist/adapters/http/request/helpers/mfa-login-ticket.mjs.map +1 -0
  231. package/dist/adapters/http/request/index.d.ts +3 -0
  232. package/dist/adapters/http/request/index.d.ts.map +1 -1
  233. package/dist/adapters/http/request/index.mjs +5 -2
  234. package/dist/adapters/http/request/types.d.ts +3 -0
  235. package/dist/adapters/http/request/types.d.ts.map +1 -0
  236. package/dist/adapters/http/ui/render.mjs +2 -2
  237. package/dist/app/index.mjs +11 -5
  238. package/dist/app/modules/components/module.d.ts.map +1 -1
  239. package/dist/app/modules/components/module.mjs +22 -2
  240. package/dist/app/modules/components/module.mjs.map +1 -1
  241. package/dist/app/modules/config/constants.d.ts +14 -0
  242. package/dist/app/modules/config/constants.d.ts.map +1 -1
  243. package/dist/app/modules/config/constants.mjs +14 -0
  244. package/dist/app/modules/config/constants.mjs.map +1 -1
  245. package/dist/app/modules/config/normalize.d.ts.map +1 -1
  246. package/dist/app/modules/config/normalize.mjs +30 -2
  247. package/dist/app/modules/config/normalize.mjs.map +1 -1
  248. package/dist/app/modules/config/read/env.d.ts.map +1 -1
  249. package/dist/app/modules/config/read/env.mjs +57 -0
  250. package/dist/app/modules/config/read/env.mjs.map +1 -1
  251. package/dist/app/modules/config/types.d.ts +101 -0
  252. package/dist/app/modules/config/types.d.ts.map +1 -1
  253. package/dist/app/modules/config/validator.d.ts.map +1 -1
  254. package/dist/app/modules/config/validator.mjs +16 -0
  255. package/dist/app/modules/config/validator.mjs.map +1 -1
  256. package/dist/app/modules/database/constants.d.ts +3 -0
  257. package/dist/app/modules/database/constants.d.ts.map +1 -1
  258. package/dist/app/modules/database/constants.mjs +3 -1
  259. package/dist/app/modules/database/constants.mjs.map +1 -1
  260. package/dist/app/modules/database/index.mjs +7 -3
  261. package/dist/app/modules/database/module.d.ts +1 -0
  262. package/dist/app/modules/database/module.d.ts.map +1 -1
  263. package/dist/app/modules/database/module.mjs +32 -1
  264. package/dist/app/modules/database/module.mjs.map +1 -1
  265. package/dist/app/modules/database/repositories/client/repository.d.ts.map +1 -1
  266. package/dist/app/modules/database/repositories/client/repository.mjs +8 -4
  267. package/dist/app/modules/database/repositories/client/repository.mjs.map +1 -1
  268. package/dist/app/modules/database/repositories/event/index.d.ts.map +1 -0
  269. package/dist/app/modules/database/repositories/event/index.mjs +5 -0
  270. package/dist/app/modules/database/repositories/event/repository.d.ts +15 -0
  271. package/dist/app/modules/database/repositories/event/repository.d.ts.map +1 -0
  272. package/dist/app/modules/database/repositories/event/repository.mjs +113 -0
  273. package/dist/app/modules/database/repositories/event/repository.mjs.map +1 -0
  274. package/dist/app/modules/database/repositories/helpers.d.ts +4 -2
  275. package/dist/app/modules/database/repositories/helpers.d.ts.map +1 -1
  276. package/dist/app/modules/database/repositories/helpers.mjs +7 -3
  277. package/dist/app/modules/database/repositories/helpers.mjs.map +1 -1
  278. package/dist/app/modules/database/repositories/index.d.ts +4 -0
  279. package/dist/app/modules/database/repositories/index.d.ts.map +1 -1
  280. package/dist/app/modules/database/repositories/index.mjs +9 -1
  281. package/dist/app/modules/database/repositories/key/index.d.ts +2 -0
  282. package/dist/app/modules/database/repositories/key/index.d.ts.map +1 -0
  283. package/dist/app/modules/database/repositories/key/index.mjs +5 -0
  284. package/dist/app/modules/database/repositories/key/repository.d.ts +50 -0
  285. package/dist/app/modules/database/repositories/key/repository.d.ts.map +1 -0
  286. package/dist/app/modules/database/repositories/key/repository.mjs +273 -0
  287. package/dist/app/modules/database/repositories/key/repository.mjs.map +1 -0
  288. package/dist/app/modules/database/repositories/permission-provider/module.mjs +1 -1
  289. package/dist/app/modules/database/repositories/trust-anchor/index.d.ts +2 -0
  290. package/dist/app/modules/database/repositories/trust-anchor/index.d.ts.map +1 -0
  291. package/dist/app/modules/database/repositories/trust-anchor/index.mjs +5 -0
  292. package/dist/app/modules/database/repositories/trust-anchor/repository.d.ts +24 -0
  293. package/dist/app/modules/database/repositories/trust-anchor/repository.d.ts.map +1 -0
  294. package/dist/app/modules/database/repositories/trust-anchor/repository.mjs +113 -0
  295. package/dist/app/modules/database/repositories/trust-anchor/repository.mjs.map +1 -0
  296. package/dist/app/modules/database/repositories/user-authenticator/index.d.ts +2 -0
  297. package/dist/app/modules/database/repositories/user-authenticator/index.d.ts.map +1 -0
  298. package/dist/app/modules/database/repositories/user-authenticator/index.mjs +5 -0
  299. package/dist/app/modules/database/repositories/user-authenticator/repository.d.ts +19 -0
  300. package/dist/app/modules/database/repositories/user-authenticator/repository.d.ts.map +1 -0
  301. package/dist/app/modules/database/repositories/user-authenticator/repository.mjs +92 -0
  302. package/dist/app/modules/database/repositories/user-authenticator/repository.mjs.map +1 -0
  303. package/dist/app/modules/http/module.d.ts +8 -0
  304. package/dist/app/modules/http/module.d.ts.map +1 -1
  305. package/dist/app/modules/http/module.mjs +19 -1
  306. package/dist/app/modules/http/module.mjs.map +1 -1
  307. package/dist/app/modules/http/modules/controller.d.ts +16 -3
  308. package/dist/app/modules/http/modules/controller.d.ts.map +1 -1
  309. package/dist/app/modules/http/modules/controller.mjs +186 -15
  310. package/dist/app/modules/http/modules/controller.mjs.map +1 -1
  311. package/dist/app/modules/http/modules/middleware.d.ts +1 -0
  312. package/dist/app/modules/http/modules/middleware.d.ts.map +1 -1
  313. package/dist/app/modules/http/modules/middleware.mjs +10 -4
  314. package/dist/app/modules/http/modules/middleware.mjs.map +1 -1
  315. package/dist/app/modules/identity/module.mjs +2 -2
  316. package/dist/app/modules/index.d.ts +1 -0
  317. package/dist/app/modules/index.d.ts.map +1 -1
  318. package/dist/app/modules/index.mjs +13 -6
  319. package/dist/app/modules/mail/module.d.ts.map +1 -1
  320. package/dist/app/modules/mail/module.mjs +2 -1
  321. package/dist/app/modules/mail/module.mjs.map +1 -1
  322. package/dist/app/modules/metrics/constants.d.ts +4 -0
  323. package/dist/app/modules/metrics/constants.d.ts.map +1 -0
  324. package/dist/app/modules/metrics/constants.mjs +10 -0
  325. package/dist/app/modules/metrics/constants.mjs.map +1 -0
  326. package/dist/app/modules/metrics/index.d.ts +3 -0
  327. package/dist/app/modules/metrics/index.d.ts.map +1 -0
  328. package/dist/app/modules/metrics/index.mjs +6 -0
  329. package/dist/app/modules/metrics/prom.d.ts +15 -0
  330. package/dist/app/modules/metrics/prom.d.ts.map +1 -0
  331. package/dist/app/modules/metrics/prom.mjs +42 -0
  332. package/dist/app/modules/metrics/prom.mjs.map +1 -0
  333. package/dist/app/modules/oauth2/constants.d.ts +9 -2
  334. package/dist/app/modules/oauth2/constants.d.ts.map +1 -1
  335. package/dist/app/modules/oauth2/constants.mjs +7 -1
  336. package/dist/app/modules/oauth2/constants.mjs.map +1 -1
  337. package/dist/app/modules/oauth2/module.d.ts.map +1 -1
  338. package/dist/app/modules/oauth2/module.mjs +23 -4
  339. package/dist/app/modules/oauth2/module.mjs.map +1 -1
  340. package/dist/app/modules/oauth2/repositories/consent/index.d.ts +2 -0
  341. package/dist/app/modules/oauth2/repositories/consent/index.d.ts.map +1 -0
  342. package/dist/app/modules/oauth2/repositories/consent/index.mjs +5 -0
  343. package/dist/app/modules/oauth2/repositories/consent/repository.d.ts +20 -0
  344. package/dist/app/modules/oauth2/repositories/consent/repository.d.ts.map +1 -0
  345. package/dist/app/modules/oauth2/repositories/consent/repository.mjs +116 -0
  346. package/dist/app/modules/oauth2/repositories/consent/repository.mjs.map +1 -0
  347. package/dist/app/modules/oauth2/repositories/index.d.ts +1 -1
  348. package/dist/app/modules/oauth2/repositories/index.d.ts.map +1 -1
  349. package/dist/app/modules/oauth2/repositories/index.mjs +3 -3
  350. package/dist/app/modules/oauth2/repositories/token/repository.d.ts +1 -0
  351. package/dist/app/modules/oauth2/repositories/token/repository.d.ts.map +1 -1
  352. package/dist/app/modules/oauth2/repositories/token/repository.mjs +8 -0
  353. package/dist/app/modules/oauth2/repositories/token/repository.mjs.map +1 -1
  354. package/dist/app/modules/provisioning/module.d.ts.map +1 -1
  355. package/dist/app/modules/provisioning/module.mjs +16 -5
  356. package/dist/app/modules/provisioning/module.mjs.map +1 -1
  357. package/dist/app/modules/provisioning/sources/default/module.d.ts.map +1 -1
  358. package/dist/app/modules/provisioning/sources/default/module.mjs +22 -7
  359. package/dist/app/modules/provisioning/sources/default/module.mjs.map +1 -1
  360. package/dist/app/modules/provisioning/sources/file/module.d.ts.map +1 -1
  361. package/dist/app/modules/provisioning/sources/file/module.mjs +12 -2
  362. package/dist/app/modules/provisioning/sources/file/module.mjs.map +1 -1
  363. package/dist/components/event-cleaner/index.d.ts +2 -0
  364. package/dist/components/event-cleaner/index.d.ts.map +1 -0
  365. package/dist/components/event-cleaner/index.mjs +5 -0
  366. package/dist/components/event-cleaner/module.d.ts +5 -0
  367. package/dist/components/event-cleaner/module.d.ts.map +1 -0
  368. package/dist/components/event-cleaner/module.mjs +30 -0
  369. package/dist/components/event-cleaner/module.mjs.map +1 -0
  370. package/dist/components/index.d.ts +1 -0
  371. package/dist/components/index.d.ts.map +1 -1
  372. package/dist/components/index.mjs +3 -1
  373. package/dist/components/oauth2-cleaner/module.d.ts +2 -1
  374. package/dist/components/oauth2-cleaner/module.d.ts.map +1 -1
  375. package/dist/components/oauth2-cleaner/module.mjs +9 -4
  376. package/dist/components/oauth2-cleaner/module.mjs.map +1 -1
  377. package/dist/core/authentication/credential/entities/client/module.d.ts +1 -1
  378. package/dist/core/authentication/credential/entities/client/module.d.ts.map +1 -1
  379. package/dist/core/authentication/credential/entities/client/module.mjs +2 -1
  380. package/dist/core/authentication/credential/entities/client/module.mjs.map +1 -1
  381. package/dist/core/authentication/entities/client/module.mjs +2 -2
  382. package/dist/core/authentication/entities/client/module.mjs.map +1 -1
  383. package/dist/core/authentication/index.d.ts +1 -0
  384. package/dist/core/authentication/index.d.ts.map +1 -1
  385. package/dist/core/authentication/index.mjs +3 -1
  386. package/dist/core/authentication/login-throttle/index.d.ts +3 -0
  387. package/dist/core/authentication/login-throttle/index.d.ts.map +1 -0
  388. package/dist/core/authentication/login-throttle/index.mjs +5 -0
  389. package/dist/core/authentication/login-throttle/service.d.ts +13 -0
  390. package/dist/core/authentication/login-throttle/service.d.ts.map +1 -0
  391. package/dist/core/authentication/login-throttle/service.mjs +33 -0
  392. package/dist/core/authentication/login-throttle/service.mjs.map +1 -0
  393. package/dist/core/authentication/login-throttle/types.d.ts +34 -0
  394. package/dist/core/authentication/login-throttle/types.d.ts.map +1 -0
  395. package/dist/core/authentication/session/module.d.ts +1 -0
  396. package/dist/core/authentication/session/module.d.ts.map +1 -1
  397. package/dist/core/authentication/session/module.mjs +4 -0
  398. package/dist/core/authentication/session/module.mjs.map +1 -1
  399. package/dist/core/authentication/session/types.d.ts +6 -0
  400. package/dist/core/authentication/session/types.d.ts.map +1 -1
  401. package/dist/core/authentication/session/types.mjs.map +1 -1
  402. package/dist/core/client-certificate/index.d.ts +3 -0
  403. package/dist/core/client-certificate/index.d.ts.map +1 -0
  404. package/dist/core/client-certificate/index.mjs +5 -0
  405. package/dist/core/client-certificate/module.d.ts +18 -0
  406. package/dist/core/client-certificate/module.d.ts.map +1 -0
  407. package/dist/core/client-certificate/module.mjs +195 -0
  408. package/dist/core/client-certificate/module.mjs.map +1 -0
  409. package/dist/core/client-certificate/types.d.ts +22 -0
  410. package/dist/core/client-certificate/types.d.ts.map +1 -0
  411. package/dist/core/client-certificate/types.mjs +4 -0
  412. package/dist/core/entities/client/service.d.ts.map +1 -1
  413. package/dist/core/entities/client/service.mjs +15 -7
  414. package/dist/core/entities/client/service.mjs.map +1 -1
  415. package/dist/core/entities/client/web-client.d.ts.map +1 -1
  416. package/dist/core/entities/client/web-client.mjs +3 -2
  417. package/dist/core/entities/client/web-client.mjs.map +1 -1
  418. package/dist/core/entities/consent/index.d.ts +3 -0
  419. package/dist/core/entities/consent/index.d.ts.map +1 -0
  420. package/dist/core/entities/consent/index.mjs +6 -0
  421. package/dist/core/entities/consent/service.d.ts +19 -0
  422. package/dist/core/entities/consent/service.d.ts.map +1 -0
  423. package/dist/core/entities/consent/service.mjs +122 -0
  424. package/dist/core/entities/consent/service.mjs.map +1 -0
  425. package/dist/core/entities/consent/types.d.ts +97 -0
  426. package/dist/core/entities/consent/types.d.ts.map +1 -0
  427. package/dist/core/entities/consent/types.mjs +25 -0
  428. package/dist/core/entities/consent/types.mjs.map +1 -0
  429. package/dist/core/entities/event/constants.d.ts +7 -0
  430. package/dist/core/entities/event/constants.d.ts.map +1 -0
  431. package/dist/core/entities/event/constants.mjs +13 -0
  432. package/dist/core/entities/event/constants.mjs.map +1 -0
  433. package/dist/core/entities/event/diff.d.ts +20 -0
  434. package/dist/core/entities/event/diff.d.ts.map +1 -0
  435. package/dist/core/entities/event/diff.mjs +45 -0
  436. package/dist/core/entities/event/diff.mjs.map +1 -0
  437. package/dist/core/entities/event/entity-event-handler.d.ts +19 -0
  438. package/dist/core/entities/event/entity-event-handler.d.ts.map +1 -0
  439. package/dist/core/entities/event/entity-event-handler.mjs +100 -0
  440. package/dist/core/entities/event/entity-event-handler.mjs.map +1 -0
  441. package/dist/core/entities/event/index.d.ts +7 -0
  442. package/dist/core/entities/event/index.d.ts.map +1 -0
  443. package/dist/core/entities/event/index.mjs +9 -0
  444. package/dist/core/entities/event/sanitize.d.ts +2 -0
  445. package/dist/core/entities/event/sanitize.d.ts.map +1 -0
  446. package/dist/core/entities/event/sanitize.mjs +83 -0
  447. package/dist/core/entities/event/sanitize.mjs.map +1 -0
  448. package/dist/core/entities/event/service.d.ts +22 -0
  449. package/dist/core/entities/event/service.d.ts.map +1 -0
  450. package/dist/core/entities/event/service.mjs +169 -0
  451. package/dist/core/entities/event/service.mjs.map +1 -0
  452. package/dist/core/entities/event/types.d.ts +124 -0
  453. package/dist/core/entities/event/types.d.ts.map +1 -0
  454. package/dist/core/entities/event/types.mjs +4 -0
  455. package/dist/core/entities/identity-provider-role-mapping/service.mjs +2 -2
  456. package/dist/core/entities/identity-provider-role-mapping/service.mjs.map +1 -1
  457. package/dist/core/entities/index.d.ts +5 -0
  458. package/dist/core/entities/index.d.ts.map +1 -1
  459. package/dist/core/entities/index.mjs +20 -1
  460. package/dist/core/entities/key/index.d.ts +3 -0
  461. package/dist/core/entities/key/index.d.ts.map +1 -0
  462. package/dist/core/entities/key/index.mjs +5 -0
  463. package/dist/core/entities/key/service.d.ts +55 -0
  464. package/dist/core/entities/key/service.d.ts.map +1 -0
  465. package/dist/core/entities/key/service.mjs +301 -0
  466. package/dist/core/entities/key/service.mjs.map +1 -0
  467. package/dist/core/entities/key/types.d.ts +33 -0
  468. package/dist/core/entities/key/types.d.ts.map +1 -0
  469. package/dist/core/entities/key/types.mjs +4 -0
  470. package/dist/core/entities/permission/service.mjs +3 -3
  471. package/dist/core/entities/permission/service.mjs.map +1 -1
  472. package/dist/core/entities/policy/service.mjs +4 -4
  473. package/dist/core/entities/policy/service.mjs.map +1 -1
  474. package/dist/core/entities/realm/service.d.ts +3 -0
  475. package/dist/core/entities/realm/service.d.ts.map +1 -1
  476. package/dist/core/entities/realm/service.mjs +6 -3
  477. package/dist/core/entities/realm/service.mjs.map +1 -1
  478. package/dist/core/entities/role/service.mjs +2 -2
  479. package/dist/core/entities/role/service.mjs.map +1 -1
  480. package/dist/core/entities/role-attribute/service.mjs +3 -3
  481. package/dist/core/entities/role-attribute/service.mjs.map +1 -1
  482. package/dist/core/entities/session/service.mjs +5 -2
  483. package/dist/core/entities/session/service.mjs.map +1 -1
  484. package/dist/core/entities/trust-anchor/index.d.ts +3 -0
  485. package/dist/core/entities/trust-anchor/index.d.ts.map +1 -0
  486. package/dist/core/entities/trust-anchor/index.mjs +5 -0
  487. package/dist/core/entities/trust-anchor/service.d.ts +33 -0
  488. package/dist/core/entities/trust-anchor/service.d.ts.map +1 -0
  489. package/dist/core/entities/trust-anchor/service.mjs +175 -0
  490. package/dist/core/entities/trust-anchor/service.mjs.map +1 -0
  491. package/dist/core/entities/trust-anchor/types.d.ts +14 -0
  492. package/dist/core/entities/trust-anchor/types.d.ts.map +1 -0
  493. package/dist/core/entities/trust-anchor/types.mjs +4 -0
  494. package/dist/core/entities/user/service.mjs +2 -2
  495. package/dist/core/entities/user/service.mjs.map +1 -1
  496. package/dist/core/entities/user-attribute/service.mjs +4 -4
  497. package/dist/core/entities/user-attribute/service.mjs.map +1 -1
  498. package/dist/core/entities/user-authenticator/constants.d.ts +26 -0
  499. package/dist/core/entities/user-authenticator/constants.d.ts.map +1 -0
  500. package/dist/core/entities/user-authenticator/constants.mjs +32 -0
  501. package/dist/core/entities/user-authenticator/constants.mjs.map +1 -0
  502. package/dist/core/entities/user-authenticator/helpers.d.ts +10 -0
  503. package/dist/core/entities/user-authenticator/helpers.d.ts.map +1 -0
  504. package/dist/core/entities/user-authenticator/helpers.mjs +35 -0
  505. package/dist/core/entities/user-authenticator/helpers.mjs.map +1 -0
  506. package/dist/core/entities/user-authenticator/index.d.ts +6 -0
  507. package/dist/core/entities/user-authenticator/index.d.ts.map +1 -0
  508. package/dist/core/entities/user-authenticator/index.mjs +9 -0
  509. package/dist/core/entities/user-authenticator/service.d.ts +89 -0
  510. package/dist/core/entities/user-authenticator/service.d.ts.map +1 -0
  511. package/dist/core/entities/user-authenticator/service.mjs +709 -0
  512. package/dist/core/entities/user-authenticator/service.mjs.map +1 -0
  513. package/dist/core/entities/user-authenticator/types.d.ts +221 -0
  514. package/dist/core/entities/user-authenticator/types.d.ts.map +1 -0
  515. package/dist/core/entities/user-authenticator/types.mjs +15 -0
  516. package/dist/core/entities/user-authenticator/types.mjs.map +1 -0
  517. package/dist/core/entities/user-authenticator/webauthn.d.ts +28 -0
  518. package/dist/core/entities/user-authenticator/webauthn.d.ts.map +1 -0
  519. package/dist/core/entities/user-authenticator/webauthn.mjs +88 -0
  520. package/dist/core/entities/user-authenticator/webauthn.mjs.map +1 -0
  521. package/dist/core/identity/index.mjs +2 -1
  522. package/dist/core/identity/password-recovery/disabled.d.ts +2 -2
  523. package/dist/core/identity/password-recovery/disabled.d.ts.map +1 -1
  524. package/dist/core/identity/password-recovery/disabled.mjs +2 -2
  525. package/dist/core/identity/password-recovery/disabled.mjs.map +1 -1
  526. package/dist/core/identity/password-recovery/email-verification-required.d.ts +2 -2
  527. package/dist/core/identity/password-recovery/email-verification-required.d.ts.map +1 -1
  528. package/dist/core/identity/password-recovery/email-verification-required.mjs +2 -2
  529. package/dist/core/identity/password-recovery/email-verification-required.mjs.map +1 -1
  530. package/dist/core/identity/password-recovery/service.d.ts +2 -1
  531. package/dist/core/identity/password-recovery/service.d.ts.map +1 -1
  532. package/dist/core/identity/password-recovery/service.mjs +26 -4
  533. package/dist/core/identity/password-recovery/service.mjs.map +1 -1
  534. package/dist/core/identity/password-recovery/token-expired.d.ts +2 -2
  535. package/dist/core/identity/password-recovery/token-expired.d.ts.map +1 -1
  536. package/dist/core/identity/password-recovery/token-expired.mjs +2 -2
  537. package/dist/core/identity/password-recovery/token-expired.mjs.map +1 -1
  538. package/dist/core/identity/password-recovery/types.d.ts +2 -1
  539. package/dist/core/identity/password-recovery/types.d.ts.map +1 -1
  540. package/dist/core/identity/permission/index.d.ts +1 -0
  541. package/dist/core/identity/permission/index.d.ts.map +1 -1
  542. package/dist/core/identity/permission/index.mjs +2 -1
  543. package/dist/core/identity/policy/checker/service.mjs +1 -1
  544. package/dist/core/identity/policy/checker/service.mjs.map +1 -1
  545. package/dist/core/identity/provider/authentication/protocols/oauth2/module.mjs +2 -2
  546. package/dist/core/identity/provider/authentication/protocols/oauth2/module.mjs.map +1 -1
  547. package/dist/core/identity/registration/error.d.ts +2 -2
  548. package/dist/core/identity/registration/error.d.ts.map +1 -1
  549. package/dist/core/identity/registration/error.mjs +2 -2
  550. package/dist/core/identity/registration/error.mjs.map +1 -1
  551. package/dist/core/identity/registration/service.d.ts +2 -1
  552. package/dist/core/identity/registration/service.d.ts.map +1 -1
  553. package/dist/core/identity/registration/service.mjs +26 -4
  554. package/dist/core/identity/registration/service.mjs.map +1 -1
  555. package/dist/core/identity/registration/types.d.ts +2 -1
  556. package/dist/core/identity/registration/types.d.ts.map +1 -1
  557. package/dist/core/index.d.ts +3 -0
  558. package/dist/core/index.d.ts.map +1 -1
  559. package/dist/core/index.mjs +39 -8
  560. package/dist/core/key/certificate-error.d.ts +10 -0
  561. package/dist/core/key/certificate-error.d.ts.map +1 -0
  562. package/dist/core/key/certificate-error.mjs +19 -0
  563. package/dist/core/key/certificate-error.mjs.map +1 -0
  564. package/dist/core/key/certificate.d.ts +15 -0
  565. package/dist/core/key/certificate.d.ts.map +1 -0
  566. package/dist/core/key/certificate.mjs +72 -0
  567. package/dist/core/key/certificate.mjs.map +1 -0
  568. package/dist/core/key/check.d.ts +3 -0
  569. package/dist/core/key/check.d.ts.map +1 -0
  570. package/dist/core/key/check.mjs +13 -0
  571. package/dist/core/key/check.mjs.map +1 -0
  572. package/dist/core/key/constants.d.ts +10 -0
  573. package/dist/core/key/constants.d.ts.map +1 -0
  574. package/dist/core/key/constants.mjs +15 -0
  575. package/dist/core/key/constants.mjs.map +1 -0
  576. package/dist/core/key/error.d.ts +14 -0
  577. package/dist/core/key/error.d.ts.map +1 -0
  578. package/dist/core/key/error.mjs +23 -0
  579. package/dist/core/key/error.mjs.map +1 -0
  580. package/dist/core/key/index.d.ts +10 -0
  581. package/dist/core/key/index.d.ts.map +1 -0
  582. package/dist/core/key/index.mjs +12 -0
  583. package/dist/core/key/provisioner.d.ts +22 -0
  584. package/dist/core/key/provisioner.d.ts.map +1 -0
  585. package/dist/core/key/provisioner.mjs +30 -0
  586. package/dist/core/key/provisioner.mjs.map +1 -0
  587. package/dist/core/key/realm-cipher.d.ts +20 -0
  588. package/dist/core/key/realm-cipher.d.ts.map +1 -0
  589. package/dist/core/key/realm-cipher.mjs +60 -0
  590. package/dist/core/key/realm-cipher.mjs.map +1 -0
  591. package/dist/core/key/types.d.ts +59 -0
  592. package/dist/core/key/types.d.ts.map +1 -0
  593. package/dist/core/key/types.mjs +4 -0
  594. package/dist/core/key/wrap.d.ts +5 -0
  595. package/dist/core/key/wrap.d.ts.map +1 -0
  596. package/dist/core/key/wrap.mjs +21 -0
  597. package/dist/core/key/wrap.mjs.map +1 -0
  598. package/dist/core/mail/template/registry.d.ts.map +1 -1
  599. package/dist/core/mail/template/registry.mjs +3 -1
  600. package/dist/core/mail/template/registry.mjs.map +1 -1
  601. package/dist/core/mail/template/templates/mfa-email-otp.d.ts +3 -0
  602. package/dist/core/mail/template/templates/mfa-email-otp.d.ts.map +1 -0
  603. package/dist/core/mail/template/templates/mfa-email-otp.mjs +34 -0
  604. package/dist/core/mail/template/templates/mfa-email-otp.mjs.map +1 -0
  605. package/dist/core/mail/template/types.d.ts +6 -1
  606. package/dist/core/mail/template/types.d.ts.map +1 -1
  607. package/dist/core/mail/template/types.mjs +1 -0
  608. package/dist/core/mail/template/types.mjs.map +1 -1
  609. package/dist/core/metrics/index.d.ts +3 -0
  610. package/dist/core/metrics/index.d.ts.map +1 -0
  611. package/dist/core/metrics/index.mjs +5 -0
  612. package/dist/core/metrics/noop.d.ts +8 -0
  613. package/dist/core/metrics/noop.d.ts.map +1 -0
  614. package/dist/core/metrics/noop.mjs +14 -0
  615. package/dist/core/metrics/noop.mjs.map +1 -0
  616. package/dist/core/metrics/types.d.ts +19 -0
  617. package/dist/core/metrics/types.d.ts.map +1 -0
  618. package/dist/core/metrics/types.mjs +4 -0
  619. package/dist/core/oauth2/access-policy/index.d.ts +3 -0
  620. package/dist/core/oauth2/access-policy/index.d.ts.map +1 -0
  621. package/dist/core/oauth2/access-policy/index.mjs +5 -0
  622. package/dist/core/oauth2/access-policy/module.d.ts +12 -0
  623. package/dist/core/oauth2/access-policy/module.d.ts.map +1 -0
  624. package/dist/core/oauth2/access-policy/module.mjs +32 -0
  625. package/dist/core/oauth2/access-policy/module.mjs.map +1 -0
  626. package/dist/core/oauth2/access-policy/types.d.ts +19 -0
  627. package/dist/core/oauth2/access-policy/types.d.ts.map +1 -0
  628. package/dist/core/oauth2/access-policy/types.mjs +4 -0
  629. package/dist/core/oauth2/authorization/code/issuer/module.d.ts.map +1 -1
  630. package/dist/core/oauth2/authorization/code/issuer/module.mjs +2 -0
  631. package/dist/core/oauth2/authorization/code/issuer/module.mjs.map +1 -1
  632. package/dist/core/oauth2/authorization/code/issuer/types.d.ts +6 -1
  633. package/dist/core/oauth2/authorization/code/issuer/types.d.ts.map +1 -1
  634. package/dist/core/oauth2/authorization/code/verifier/module.mjs.map +1 -1
  635. package/dist/core/oauth2/authorization/code-request/validator.d.ts.map +1 -1
  636. package/dist/core/oauth2/authorization/code-request/validator.mjs +1 -0
  637. package/dist/core/oauth2/authorization/code-request/validator.mjs.map +1 -1
  638. package/dist/core/oauth2/authorization/code-request/verifier/module.mjs +3 -3
  639. package/dist/core/oauth2/authorization/code-request/verifier/module.mjs.map +1 -1
  640. package/dist/core/oauth2/authorization/helpers.d.ts +10 -1
  641. package/dist/core/oauth2/authorization/helpers.d.ts.map +1 -1
  642. package/dist/core/oauth2/authorization/helpers.mjs +28 -2
  643. package/dist/core/oauth2/authorization/helpers.mjs.map +1 -1
  644. package/dist/core/oauth2/authorization/index.mjs +2 -2
  645. package/dist/core/oauth2/authorization/module.d.ts +9 -0
  646. package/dist/core/oauth2/authorization/module.d.ts.map +1 -1
  647. package/dist/core/oauth2/authorization/module.mjs +80 -3
  648. package/dist/core/oauth2/authorization/module.mjs.map +1 -1
  649. package/dist/core/oauth2/authorization/types.d.ts +36 -0
  650. package/dist/core/oauth2/authorization/types.d.ts.map +1 -1
  651. package/dist/core/oauth2/client/authenticator.d.ts +16 -7
  652. package/dist/core/oauth2/client/authenticator.d.ts.map +1 -1
  653. package/dist/core/oauth2/client/authenticator.mjs +49 -12
  654. package/dist/core/oauth2/client/authenticator.mjs.map +1 -1
  655. package/dist/core/oauth2/end-session/service.d.ts +2 -1
  656. package/dist/core/oauth2/end-session/service.d.ts.map +1 -1
  657. package/dist/core/oauth2/end-session/service.mjs +13 -0
  658. package/dist/core/oauth2/end-session/service.mjs.map +1 -1
  659. package/dist/core/oauth2/end-session/types.d.ts +2 -1
  660. package/dist/core/oauth2/end-session/types.d.ts.map +1 -1
  661. package/dist/core/oauth2/grant-types/authorize.d.ts +2 -2
  662. package/dist/core/oauth2/grant-types/authorize.d.ts.map +1 -1
  663. package/dist/core/oauth2/grant-types/authorize.mjs +12 -8
  664. package/dist/core/oauth2/grant-types/authorize.mjs.map +1 -1
  665. package/dist/core/oauth2/grant-types/client-credentials.d.ts.map +1 -1
  666. package/dist/core/oauth2/grant-types/client-credentials.mjs +5 -3
  667. package/dist/core/oauth2/grant-types/client-credentials.mjs.map +1 -1
  668. package/dist/core/oauth2/grant-types/identity.d.ts.map +1 -1
  669. package/dist/core/oauth2/grant-types/identity.mjs +10 -3
  670. package/dist/core/oauth2/grant-types/identity.mjs.map +1 -1
  671. package/dist/core/oauth2/grant-types/password.d.ts +9 -0
  672. package/dist/core/oauth2/grant-types/password.d.ts.map +1 -1
  673. package/dist/core/oauth2/grant-types/password.mjs +32 -4
  674. package/dist/core/oauth2/grant-types/password.mjs.map +1 -1
  675. package/dist/core/oauth2/grant-types/refresh-token.d.ts +4 -0
  676. package/dist/core/oauth2/grant-types/refresh-token.d.ts.map +1 -1
  677. package/dist/core/oauth2/grant-types/refresh-token.mjs +17 -1
  678. package/dist/core/oauth2/grant-types/refresh-token.mjs.map +1 -1
  679. package/dist/core/oauth2/grant-types/robot-credentials.d.ts.map +1 -1
  680. package/dist/core/oauth2/grant-types/robot-credentials.mjs +3 -2
  681. package/dist/core/oauth2/grant-types/robot-credentials.mjs.map +1 -1
  682. package/dist/core/oauth2/grant-types/types.d.ts +10 -3
  683. package/dist/core/oauth2/grant-types/types.d.ts.map +1 -1
  684. package/dist/core/oauth2/index.d.ts +2 -1
  685. package/dist/core/oauth2/index.d.ts.map +1 -1
  686. package/dist/core/oauth2/index.mjs +7 -2
  687. package/dist/core/oauth2/mfa-login/index.d.ts +3 -0
  688. package/dist/core/oauth2/mfa-login/index.d.ts.map +1 -0
  689. package/dist/core/oauth2/mfa-login/index.mjs +5 -0
  690. package/dist/core/oauth2/mfa-login/module.d.ts +19 -0
  691. package/dist/core/oauth2/mfa-login/module.d.ts.map +1 -0
  692. package/dist/core/oauth2/mfa-login/module.mjs +109 -0
  693. package/dist/core/oauth2/mfa-login/module.mjs.map +1 -0
  694. package/dist/core/oauth2/mfa-login/types.d.ts +64 -0
  695. package/dist/core/oauth2/mfa-login/types.d.ts.map +1 -0
  696. package/dist/core/oauth2/mfa-login/types.mjs +4 -0
  697. package/dist/core/oauth2/token/index.mjs +2 -1
  698. package/dist/core/oauth2/token/issuer/index.d.ts +1 -0
  699. package/dist/core/oauth2/token/issuer/index.d.ts.map +1 -1
  700. package/dist/core/oauth2/token/issuer/index.mjs +3 -1
  701. package/dist/core/oauth2/token/issuer/mfa/index.d.ts +2 -0
  702. package/dist/core/oauth2/token/issuer/mfa/index.d.ts.map +1 -0
  703. package/dist/core/oauth2/token/issuer/mfa/index.mjs +5 -0
  704. package/dist/core/oauth2/token/issuer/mfa/module.d.ts +18 -0
  705. package/dist/core/oauth2/token/issuer/mfa/module.d.ts.map +1 -0
  706. package/dist/core/oauth2/token/issuer/mfa/module.mjs +36 -0
  707. package/dist/core/oauth2/token/issuer/mfa/module.mjs.map +1 -0
  708. package/dist/core/oauth2/token/repository/types.d.ts +10 -0
  709. package/dist/core/oauth2/token/repository/types.d.ts.map +1 -1
  710. package/dist/core/oauth2/token/revoker/module.d.ts.map +1 -1
  711. package/dist/core/oauth2/token/revoker/module.mjs +1 -0
  712. package/dist/core/oauth2/token/revoker/module.mjs.map +1 -1
  713. package/dist/core/oauth2/token/signer/module.d.ts +3 -3
  714. package/dist/core/oauth2/token/signer/module.d.ts.map +1 -1
  715. package/dist/core/oauth2/token/signer/module.mjs +5 -6
  716. package/dist/core/oauth2/token/signer/module.mjs.map +1 -1
  717. package/dist/core/oauth2/token/verifier/module.d.ts +3 -3
  718. package/dist/core/oauth2/token/verifier/module.d.ts.map +1 -1
  719. package/dist/core/oauth2/token/verifier/module.mjs +8 -5
  720. package/dist/core/oauth2/token/verifier/module.mjs.map +1 -1
  721. package/dist/index.mjs +52 -30
  722. package/dist/swagger.json +5431 -2952
  723. package/dist/ui/client/.vite/ssr-manifest.json +3888 -864
  724. package/dist/ui/client/assets/index-BmWsoQro.css +2 -0
  725. package/dist/ui/client/assets/{index-CP9HCHoS.js → index-CT0Nq5pA.js} +18 -17
  726. package/dist/ui/client/index.html +2 -2
  727. package/dist/ui/server/server.js +19470 -18436
  728. package/package.json +22 -16
  729. package/dist/app/modules/oauth2/repositories/key/index.d.ts.map +0 -1
  730. package/dist/app/modules/oauth2/repositories/key/index.mjs +0 -5
  731. package/dist/app/modules/oauth2/repositories/key/repository.d.ts +0 -14
  732. package/dist/app/modules/oauth2/repositories/key/repository.d.ts.map +0 -1
  733. package/dist/app/modules/oauth2/repositories/key/repository.mjs +0 -51
  734. package/dist/app/modules/oauth2/repositories/key/repository.mjs.map +0 -1
  735. package/dist/core/oauth2/key/index.d.ts +0 -2
  736. package/dist/core/oauth2/key/index.d.ts.map +0 -1
  737. package/dist/core/oauth2/key/types.d.ts +0 -16
  738. package/dist/core/oauth2/key/types.d.ts.map +0 -1
  739. package/dist/ui/client/assets/index-VM4JXBXw.css +0 -2
  740. /package/dist/{core/oauth2/key → adapters/http/request}/types.mjs +0 -0
  741. /package/dist/app/modules/{oauth2/repositories/key → database/repositories/event}/index.d.ts +0 -0
  742. /package/dist/core/{oauth2/key/index.mjs → authentication/login-throttle/types.mjs} +0 -0
@@ -4,10 +4,12 @@ import.meta.url;
4
4
  import { assertClientGrantAllowed } from "../../../../../core/oauth2/client/grant-type.mjs";
5
5
  import { OAuth2AuthorizeGrant } from "../../../../../core/oauth2/grant-types/authorize.mjs";
6
6
  import "../../../../../core/index.mjs";
7
+ import { extractOAuth2ClientCertificateEvidence } from "./utils/certificate.mjs";
7
8
  import { extractClientCredentialsFromRequest } from "./utils/credentials.mjs";
8
9
  import { readRealmHint } from "./utils/realm.mjs";
9
10
  import "./utils/index.mjs";
10
- import { OAuth2RequestError, OAuth2TokenGrant } from "@authup/specs";
11
+ import { isClientPublic } from "@authup/core-kit";
12
+ import { OAuth2GrantError, OAuth2RequestError, OAuth2TokenGrant } from "@authup/specs";
11
13
  import { getRequestHeader, getRequestIP } from "routup";
12
14
  import { readRequestBody } from "@routup/basic/body";
13
15
  import { useRequestQuery } from "@routup/basic/query";
@@ -16,11 +18,15 @@ var HTTPOAuth2AuthorizeGrant = class extends OAuth2AuthorizeGrant {
16
18
  codeVerifier;
17
19
  clientAuthenticator;
18
20
  realmRepository;
21
+ accessPolicyEvaluator;
22
+ certificateSource;
19
23
  constructor(ctx) {
20
24
  super(ctx);
21
25
  this.codeVerifier = ctx.codeVerifier;
22
26
  this.clientAuthenticator = ctx.clientAuthenticator;
23
27
  this.realmRepository = ctx.realmRepository;
28
+ this.accessPolicyEvaluator = ctx.accessPolicyEvaluator;
29
+ this.certificateSource = ctx.certificateSource ?? "disabled";
24
30
  }
25
31
  async runWithRequest(event) {
26
32
  const body = await readRequestBody(event);
@@ -31,16 +37,30 @@ var HTTPOAuth2AuthorizeGrant = class extends OAuth2AuthorizeGrant {
31
37
  if (!code) throw OAuth2RequestError.malformed();
32
38
  const { clientId, clientSecret } = await extractClientCredentialsFromRequest(event);
33
39
  const realm = await this.realmRepository.resolve(readRealmHint(body, query), true);
34
- const client = await this.clientAuthenticator.authenticate(clientId, clientSecret, realm.id);
40
+ const certificateEvidence = await extractOAuth2ClientCertificateEvidence(event, this.certificateSource);
41
+ const client = await this.clientAuthenticator.authenticate(clientId, clientSecret, realm.id, certificateEvidence);
42
+ const confirmation = this.clientAuthenticator.resolveTokenBinding(client, certificateEvidence);
35
43
  assertClientGrantAllowed(client, OAuth2TokenGrant.AUTHORIZATION_CODE);
36
44
  const entity = await this.codeVerifier.verify(code, {
37
45
  redirectUri,
38
46
  codeVerifier,
39
47
  clientId: client.id,
40
- clientIsPublic: !client.is_confidential,
48
+ clientIsPublic: isClientPublic(client),
41
49
  realmId: client.realm_id
42
50
  });
51
+ if (client.access_policy_id) {
52
+ let allowed = false;
53
+ if (this.accessPolicyEvaluator) allowed = await this.accessPolicyEvaluator.evaluate(client.access_policy_id, {
54
+ type: entity.sub_kind,
55
+ id: entity.sub,
56
+ realmId: entity.realm_id ?? null,
57
+ realmName: entity.realm_name ?? null,
58
+ clientId: entity.client_id ?? null
59
+ });
60
+ if (!allowed) throw OAuth2GrantError.invalid();
61
+ }
43
62
  return this.runWith(entity, {
63
+ confirmation,
44
64
  ipAddress: getRequestIP(event, { trustProxy: true }) ?? void 0,
45
65
  userAgent: getRequestHeader(event, "user-agent") ?? void 0
46
66
  });
@@ -1 +1 @@
1
- {"version":3,"file":"authorize.mjs","names":["OAuth2RequestError","OAuth2TokenGrant","readRequestBody","useRequestQuery","getRequestHeader","getRequestIP","OAuth2AuthorizeGrant","assertClientGrantAllowed","extractClientCredentialsFromRequest","readRealmHint","HTTPOAuth2AuthorizeGrant","codeVerifier","clientAuthenticator","realmRepository","ctx","runWithRequest","event","body","query","code","pickStringParam","redirectUri","malformed","clientId","clientSecret","realm","resolve","client","authenticate","id","AUTHORIZATION_CODE","entity","verify","clientIsPublic","is_confidential","realmId","realm_id","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 { 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 IOAuth2AuthorizationCodeVerifier,\n IRealmRepository,\n OAuth2ClientAuthenticator,\n} from '../../../../../core/index.ts';\nimport type { HTTPOAuth2AuthorizeGrantContext, IHTTPOAuth2Grant } from './types.ts';\nimport { extractClientCredentialsFromRequest, readRealmHint } 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 constructor(ctx: HTTPOAuth2AuthorizeGrantContext) {\n super(ctx);\n\n this.codeVerifier = ctx.codeVerifier;\n this.clientAuthenticator = ctx.clientAuthenticator;\n this.realmRepository = ctx.realmRepository;\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\n const client = await this.clientAuthenticator.authenticate(clientId, clientSecret, realm.id);\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: !client.is_confidential,\n realmId: client.realm_id,\n });\n\n return this.runWith(entity, {\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":";;;;;;;;;;;;;;AAsBA,IAAaU,2BAAb,cAA8CJ,qBAAAA;CAChCK;CAEAC;CAEAC;CAEV,YAAYC,KAAsC;EAC9C,MAAMA,GAAAA;EAEN,KAAKH,eAAeG,IAAIH;EACxB,KAAKC,sBAAsBE,IAAIF;EAC/B,KAAKC,kBAAkBC,IAAID;CAC/B;CAEA,MAAME,eAAeC,OAAqD;EACtE,MAAMC,OAAO,MAAMf,gBAAgBc,KAAAA;EACnC,MAAME,QAAQf,gBAAgBa,KAAAA;EAE9B,MAAMG,OAAO,KAAKC,gBAAgBH,MAAMC,OAAO,MAAA;EAC/C,MAAMG,cAAc,KAAKD,gBAAgBH,MAAMC,OAAO,cAAA;EACtD,MAAMP,eAAe,KAAKS,gBAAgBH,MAAMC,OAAO,eAAA;EACvD,IAAI,CAACC,MACD,MAAMnB,mBAAmBsB,UAAS;EAGtC,MAAM,EAAEC,UAAUC,iBAAiB,MAAMhB,oCAAoCQ,KAAAA;EAC7E,MAAMS,QAAQ,MAAM,KAAKZ,gBAAgBa,QAAQjB,cAAcQ,MAAMC,KAAAA,GAAQ,IAAA;EAE7E,MAAMS,SAAS,MAAM,KAAKf,oBAAoBgB,aAAaL,UAAUC,cAAcC,MAAMI,EAAE;EAE3FtB,yBAAyBoB,QAAQ1B,iBAAiB6B,kBAAkB;EAEpE,MAAMC,SAAS,MAAM,KAAKpB,aAAaqB,OAAOb,MAAM;GAChDE;GACAV;GACAY,UAAUI,OAAOE;GACjBI,gBAAgB,CAACN,OAAOO;GACxBC,SAASR,OAAOS;EACpB,CAAA;EAEA,OAAO,KAAKC,QAAQN,QAAQ;GACxBO,WAAWjC,aAAaW,OAAO,EAAEuB,YAAY,KAAK,CAAA,KAAMC,KAAAA;GACxDC,WAAWrC,iBAAiBY,OAAO,YAAA,KAAiBwB,KAAAA;EACxD,CAAA;CACJ;CAEUpB,gBACNH,MACAC,OACAwB,KACkB;EAClB,MAAMC,QAAQ1B,OAAOyB,QAAQxB,QAAQwB;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","realm_id","access_policy_id","allowed","evaluate","type","sub_kind","sub","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.realm_id,\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.access_policy_id) {\n let allowed = false;\n if (this.accessPolicyEvaluator) {\n allowed = await this.accessPolicyEvaluator.evaluate(client.access_policy_id, {\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,OAAOU;EACpB,CAAA;EAOA,IAAIV,OAAOW,kBAAkB;GACzB,IAAIC,UAAU;GACd,IAAI,KAAK5B,uBACL4B,UAAU,MAAM,KAAK5B,sBAAsB6B,SAASb,OAAOW,kBAAkB;IACzEG,MAAMR,OAAOS;IACbb,IAAII,OAAOU;IACXP,SAASH,OAAOI,YAAY;IAC5BO,WAAWX,OAAOY,cAAc;IAChCvB,UAAUW,OAAOa,aAAa;GAClC,CAAA;GAGJ,IAAI,CAACP,SACD,MAAM5C,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,11 +1,12 @@
1
1
  import type { OAuth2TokenGrantResponse } from '@authup/specs';
2
- import type { Client } from '@authup/core-kit';
3
2
  import type { IAppEvent } from 'routup';
4
- import type { ICredentialsAuthenticator } from '../../../../../core/index.ts';
3
+ import type { OAuth2ClientAuthenticator } from '../../../../../core/index.ts';
5
4
  import { ClientCredentialsGrant } from '../../../../../core/index.ts';
6
5
  import type { HTTPOAuth2ClientCredentialsGrantContext, IHTTPOAuth2Grant } from './types.ts';
6
+ import type { CertificateSource } from '../../../request/index.ts';
7
7
  export declare class HTTPClientCredentialsGrant extends ClientCredentialsGrant implements IHTTPOAuth2Grant {
8
- protected authenticator: ICredentialsAuthenticator<Client>;
8
+ protected clientAuthenticator: OAuth2ClientAuthenticator;
9
+ protected certificateSource: CertificateSource;
9
10
  constructor(ctx: HTTPOAuth2ClientCredentialsGrantContext);
10
11
  runWithRequest(event: IAppEvent): Promise<OAuth2TokenGrantResponse>;
11
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client-credentials.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/client-credentials.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAG9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,sBAAsB,EAA4B,MAAM,8BAA8B,CAAC;AAChG,OAAO,KAAK,EAAE,uCAAuC,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG5F,qBAAa,0BAA2B,SAAQ,sBAAuB,YAAW,gBAAgB;IAC9F,SAAS,CAAC,aAAa,EAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;gBAEhD,GAAG,EAAE,uCAAuC;IAMlD,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,wBAAwB,CAAC;CAkB5E"}
1
+ {"version":3,"file":"client-credentials.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/client-credentials.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAI9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,sBAAsB,EAA4B,MAAM,8BAA8B,CAAC;AAChG,OAAO,KAAK,EAAE,uCAAuC,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC5F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAMnE,qBAAa,0BAA2B,SAAQ,sBAAuB,YAAW,gBAAgB;IAC9F,SAAS,CAAC,mBAAmB,EAAG,yBAAyB,CAAC;IAE1D,SAAS,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;gBAEnC,GAAG,EAAE,uCAAuC;IAOlD,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,wBAAwB,CAAC;CA6B5E"}
@@ -4,26 +4,33 @@ import.meta.url;
4
4
  import { assertClientGrantAllowed } from "../../../../../core/oauth2/client/grant-type.mjs";
5
5
  import { ClientCredentialsGrant } from "../../../../../core/oauth2/grant-types/client-credentials.mjs";
6
6
  import "../../../../../core/index.mjs";
7
+ import { extractOAuth2ClientCertificateEvidence } from "./utils/certificate.mjs";
7
8
  import { extractClientCredentialsFromRequest } from "./utils/credentials.mjs";
8
9
  import "./utils/index.mjs";
9
- import { EntityCredentialsInvalidError } from "@authup/errors";
10
- import { OAuth2TokenGrant } from "@authup/specs";
10
+ import { ClientAuthMethod } from "@authup/core-kit";
11
+ import { OAuth2ClientError, OAuth2TokenGrant } from "@authup/specs";
11
12
  import { getRequestHeader, getRequestIP } from "routup";
12
13
  import { readRequestBody } from "@routup/basic/body";
13
14
  //#region src/adapters/http/adapters/oauth2/grant-types/client-credentials.ts
14
15
  var HTTPClientCredentialsGrant = class extends ClientCredentialsGrant {
15
- authenticator;
16
+ clientAuthenticator;
17
+ certificateSource;
16
18
  constructor(ctx) {
17
19
  super(ctx);
18
- this.authenticator = ctx.authenticator;
20
+ this.clientAuthenticator = ctx.clientAuthenticator;
21
+ this.certificateSource = ctx.certificateSource ?? "disabled";
19
22
  }
20
23
  async runWithRequest(event) {
21
24
  const { clientId, clientSecret } = await extractClientCredentialsFromRequest(event);
22
25
  const realmId = (await readRequestBody(event))?.realm_id;
23
- if (!clientId) throw new EntityCredentialsInvalidError({ entity: "client" });
24
- const client = await this.authenticator.authenticate(clientId, clientSecret ?? "", realmId);
26
+ if (!clientId) throw OAuth2ClientError.invalid();
27
+ const certificateEvidence = await extractOAuth2ClientCertificateEvidence(event, this.certificateSource);
28
+ const client = await this.clientAuthenticator.authenticate(clientId, clientSecret, realmId, certificateEvidence);
29
+ if (client.auth_method === ClientAuthMethod.NONE) throw OAuth2ClientError.invalid();
30
+ const confirmation = this.clientAuthenticator.resolveTokenBinding(client, certificateEvidence);
25
31
  assertClientGrantAllowed(client, OAuth2TokenGrant.CLIENT_CREDENTIALS);
26
32
  return this.runWith(client, {
33
+ confirmation,
27
34
  ipAddress: getRequestIP(event, { trustProxy: true }) ?? void 0,
28
35
  userAgent: getRequestHeader(event, "user-agent") ?? void 0
29
36
  });
@@ -1 +1 @@
1
- {"version":3,"file":"client-credentials.mjs","names":["OAuth2TokenGrant","readRequestBody","EntityCredentialsInvalidError","getRequestHeader","getRequestIP","ClientCredentialsGrant","assertClientGrantAllowed","extractClientCredentialsFromRequest","HTTPClientCredentialsGrant","authenticator","ctx","runWithRequest","event","clientId","clientSecret","body","realmId","realm_id","entity","client","authenticate","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 { OAuth2TokenGrant } from '@authup/specs';\nimport { readRequestBody } from '@routup/basic/body';\nimport type { Client } from '@authup/core-kit';\nimport { EntityCredentialsInvalidError } from '@authup/errors';\nimport type { IAppEvent } from 'routup';\nimport { getRequestHeader, getRequestIP } from 'routup';\nimport type { ICredentialsAuthenticator } from '../../../../../core/index.ts';\nimport { ClientCredentialsGrant, assertClientGrantAllowed } from '../../../../../core/index.ts';\nimport type { HTTPOAuth2ClientCredentialsGrantContext, IHTTPOAuth2Grant } from './types.ts';\nimport { extractClientCredentialsFromRequest } from './utils/index.ts';\n\nexport class HTTPClientCredentialsGrant extends ClientCredentialsGrant implements IHTTPOAuth2Grant {\n protected authenticator : ICredentialsAuthenticator<Client>;\n\n constructor(ctx: HTTPOAuth2ClientCredentialsGrantContext) {\n super(ctx);\n\n this.authenticator = ctx.authenticator;\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 new EntityCredentialsInvalidError({ entity: 'client' });\n }\n\n const client = await this.authenticator.authenticate(clientId, clientSecret ?? '', realmId);\n\n assertClientGrantAllowed(client, OAuth2TokenGrant.CLIENT_CREDENTIALS);\n\n return this.runWith(client, {\n ipAddress: getRequestIP(event, { trustProxy: true }) ?? undefined,\n userAgent: getRequestHeader(event, 'user-agent') ?? undefined,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAmBA,IAAaQ,6BAAb,cAAgDH,uBAAAA;CAClCI;CAEV,YAAYC,KAA8C;EACtD,MAAMA,GAAAA;EAEN,KAAKD,gBAAgBC,IAAID;CAC7B;CAEA,MAAME,eAAeC,OAAqD;EACtE,MAAM,EAAEC,UAAUC,iBAAiB,MAAMP,oCAAoCK,KAAAA;EAE7E,MAAMI,WAAUD,MADGd,gBAAgBW,KAAAA,EAAAA,EACbK;EAEtB,IAAI,CAACJ,UACD,MAAM,IAAIX,8BAA8B,EAAEgB,QAAQ,SAAS,CAAA;EAG/D,MAAMC,SAAS,MAAM,KAAKV,cAAcW,aAAaP,UAAUC,gBAAgB,IAAIE,OAAAA;EAEnFV,yBAAyBa,QAAQnB,iBAAiBqB,kBAAkB;EAEpE,OAAO,KAAKC,QAAQH,QAAQ;GACxBI,WAAWnB,aAAaQ,OAAO,EAAEY,YAAY,KAAK,CAAA,KAAMC,KAAAA;GACxDC,WAAWvB,iBAAiBS,OAAO,YAAA,KAAiBa,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","auth_method","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.auth_method === 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,gBAAgBtB,iBAAiBuB,MACxC,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,6 +1,7 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
+ import { extractOAuth2ClientCertificateEvidence } from "./utils/certificate.mjs";
4
5
  import { extractClientCredentialsFromRequest, readStringField } from "./utils/credentials.mjs";
5
6
  import { guessOauth2GrantTypeByRequest } from "./utils/guess.mjs";
6
7
  import { readRealmHint } from "./utils/realm.mjs";
@@ -11,4 +12,4 @@ import { HTTPOAuth2IdentityGrantType } from "./identity.mjs";
11
12
  import { HTTPPasswordGrant } from "./password.mjs";
12
13
  import { HTTPOAuth2RefreshTokenGrant } from "./refresh_token.mjs";
13
14
  import { HTTPRobotCredentialsGrant } from "./robot-credentials.mjs";
14
- export { HTTPClientCredentialsGrant, HTTPOAuth2AuthorizeGrant, HTTPOAuth2IdentityGrantType, HTTPOAuth2RefreshTokenGrant, HTTPPasswordGrant, HTTPRobotCredentialsGrant, extractClientCredentialsFromRequest, guessOauth2GrantTypeByRequest, readRealmHint, readStringField };
15
+ export { HTTPClientCredentialsGrant, HTTPOAuth2AuthorizeGrant, HTTPOAuth2IdentityGrantType, HTTPOAuth2RefreshTokenGrant, HTTPPasswordGrant, HTTPRobotCredentialsGrant, extractClientCredentialsFromRequest, extractOAuth2ClientCertificateEvidence, guessOauth2GrantTypeByRequest, readRealmHint, readStringField };
@@ -1,14 +1,50 @@
1
1
  import type { User } from '@authup/core-kit';
2
- import type { OAuth2TokenGrantResponse } from '@authup/specs';
2
+ import { UserAuthenticatorKind } from '@authup/core-kit';
3
+ import type { Logger } from '@authup/server-kit';
4
+ import type { OAuth2TokenConfirmation, OAuth2TokenGrantResponse } from '@authup/specs';
3
5
  import type { IAppEvent } from 'routup';
4
- import type { ICredentialsAuthenticator, IRealmRepository, OAuth2ClientAuthenticator } from '../../../../../core/index.ts';
6
+ import type { ICredentialsAuthenticator, ILoginThrottleService, IOAuth2MfaLoginService, IRealmRepository, IUserAuthenticatorService, OAuth2ClientAuthenticator } from '../../../../../core/index.ts';
5
7
  import { PasswordGrantType } from '../../../../../core/index.ts';
6
8
  import type { HTTPOAuth2PasswordGrantContext, IHTTPOAuth2Grant } from './types.ts';
9
+ import type { CertificateSource } from '../../../request/index.ts';
7
10
  export declare class HTTPPasswordGrant extends PasswordGrantType implements IHTTPOAuth2Grant {
8
11
  protected authenticator: ICredentialsAuthenticator<User>;
9
12
  protected clientAuthenticator: OAuth2ClientAuthenticator;
10
13
  protected realmRepository: IRealmRepository;
14
+ protected loginThrottleService?: ILoginThrottleService;
15
+ protected userAuthenticatorService?: IUserAuthenticatorService;
16
+ protected mfaLoginService?: IOAuth2MfaLoginService;
17
+ protected logger?: Logger;
18
+ protected certificateSource: CertificateSource;
11
19
  constructor(ctx: HTTPOAuth2PasswordGrantContext);
12
20
  runWithRequest(event: IAppEvent): Promise<OAuth2TokenGrantResponse>;
21
+ /**
22
+ * MFA gate on the direct password grant: a user holding a confirmed
23
+ * device must send a valid `otp` form parameter (TOTP or recovery
24
+ * code, classified by shape) — otherwise `mfa_required`. Users
25
+ * without a device pass through (they could never enroll otherwise).
26
+ */
27
+ protected verifySecondFactor(user: User, body: Record<string, any>, ctx: {
28
+ ipAddress?: string;
29
+ userAgent?: string;
30
+ clientId: string | null;
31
+ confirmation?: OAuth2TokenConfirmation;
32
+ }): Promise<string | undefined>;
33
+ /**
34
+ * Issue the MFA-pending ticket for factor kinds that cannot complete
35
+ * inside the single grant POST (email needs a server-sent code,
36
+ * WebAuthn an interactive ceremony). TOTP/recovery-only users keep
37
+ * the inline `otp` fast-path and get no ticket — a pending session
38
+ * per plain code entry would be pure churn.
39
+ */
40
+ protected issueMfaTicket(user: User, kinds: `${UserAuthenticatorKind}`[], ctx: {
41
+ ipAddress?: string;
42
+ userAgent?: string;
43
+ clientId: string | null;
44
+ confirmation?: OAuth2TokenConfirmation;
45
+ }): Promise<{
46
+ token: string;
47
+ expiresIn: number;
48
+ } | null>;
13
49
  }
14
50
  //# sourceMappingURL=password.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/password.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAG9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,KAAK,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAC3H,OAAO,EAAE,iBAAiB,EAA4B,MAAM,8BAA8B,CAAC;AAC3F,OAAO,KAAK,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnF,qBAAa,iBAAkB,SAAQ,iBAAkB,YAAW,gBAAgB;IAChF,SAAS,CAAC,aAAa,EAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAE1D,SAAS,CAAC,mBAAmB,EAAG,yBAAyB,CAAC;IAE1D,SAAS,CAAC,eAAe,EAAG,gBAAgB,CAAC;gBAEjC,GAAG,EAAE,8BAA8B;IAQzC,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,wBAAwB,CAAC;CAmC5E"}
1
+ {"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/password.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAyB,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,KAAK,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAGvF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,KAAK,EACR,yBAAyB,EACzB,qBAAqB,EACrB,sBAAsB,EACtB,gBAAgB,EAChB,yBAAyB,EACzB,yBAAyB,EAC5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACH,iBAAiB,EAGpB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAQnE,qBAAa,iBAAkB,SAAQ,iBAAkB,YAAW,gBAAgB;IAChF,SAAS,CAAC,aAAa,EAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAE1D,SAAS,CAAC,mBAAmB,EAAG,yBAAyB,CAAC;IAE1D,SAAS,CAAC,eAAe,EAAG,gBAAgB,CAAC;IAE7C,SAAS,CAAC,oBAAoB,CAAC,EAAG,qBAAqB,CAAC;IAExD,SAAS,CAAC,wBAAwB,CAAC,EAAG,yBAAyB,CAAC;IAEhE,SAAS,CAAC,eAAe,CAAC,EAAG,sBAAsB,CAAC;IAEpD,SAAS,CAAC,MAAM,CAAC,EAAG,MAAM,CAAC;IAE3B,SAAS,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;gBAEnC,GAAG,EAAE,8BAA8B;IAazC,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,wBAAwB,CAAC;IA0FzE;;;;;OAKG;cACa,kBAAkB,CAC9B,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,GAAG,EAAE;QACD,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,YAAY,CAAC,EAAE,uBAAuB,CAAC;KAC1C,GACF,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAwD9B;;;;;;OAMG;cACa,cAAc,CAC1B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,GAAG,qBAAqB,EAAE,EAAE,EACnC,GAAG,EAAE;QACD,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,YAAY,CAAC,EAAE,uBAAuB,CAAC;KAC1C,GACD,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAkC3D"}
@@ -1,13 +1,17 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
+ import { guessUserAuthenticatorKindByResponse } from "../../../../../core/entities/user-authenticator/helpers.mjs";
4
5
  import { assertClientGrantAllowed } from "../../../../../core/oauth2/client/grant-type.mjs";
5
6
  import { PasswordGrantType } from "../../../../../core/oauth2/grant-types/password.mjs";
6
7
  import "../../../../../core/index.mjs";
8
+ import { extractOAuth2ClientCertificateEvidence } from "./utils/certificate.mjs";
7
9
  import { extractClientCredentialsFromRequest, readStringField } from "./utils/credentials.mjs";
8
10
  import { readRealmHint } from "./utils/realm.mjs";
9
11
  import "./utils/index.mjs";
10
- import { OAuth2RequestError, OAuth2TokenGrant } from "@authup/specs";
12
+ import { EventName, EventScope, UserAuthenticatorKind } from "@authup/core-kit";
13
+ import { isEntityCredentialsInvalidError, isEntityInactiveError } from "@authup/errors";
14
+ import { OAuth2MfaRequiredError, OAuth2RequestError, OAuth2TokenGrant } from "@authup/specs";
11
15
  import { getRequestHeader, getRequestIP } from "routup";
12
16
  import { readRequestBody } from "@routup/basic/body";
13
17
  //#region src/adapters/http/adapters/oauth2/grant-types/password.ts
@@ -15,11 +19,21 @@ var HTTPPasswordGrant = class extends PasswordGrantType {
15
19
  authenticator;
16
20
  clientAuthenticator;
17
21
  realmRepository;
22
+ loginThrottleService;
23
+ userAuthenticatorService;
24
+ mfaLoginService;
25
+ logger;
26
+ certificateSource;
18
27
  constructor(ctx) {
19
28
  super(ctx);
20
29
  this.authenticator = ctx.authenticator;
21
30
  this.clientAuthenticator = ctx.clientAuthenticator;
22
31
  this.realmRepository = ctx.realmRepository;
32
+ this.loginThrottleService = ctx.loginThrottleService;
33
+ this.userAuthenticatorService = ctx.userAuthenticatorService;
34
+ this.mfaLoginService = ctx.mfaLoginService;
35
+ this.logger = ctx.logger;
36
+ this.certificateSource = ctx.certificateSource ?? "disabled";
23
37
  }
24
38
  async runWithRequest(event) {
25
39
  const body = await readRequestBody(event);
@@ -28,16 +42,115 @@ var HTTPPasswordGrant = class extends PasswordGrantType {
28
42
  if (!username || !password) throw OAuth2RequestError.malformed("username and password must be provided.");
29
43
  const { clientId, clientSecret } = await extractClientCredentialsFromRequest(event);
30
44
  const realm = await this.realmRepository.resolve(readRealmHint(body), true);
31
- const client = clientId ? await this.clientAuthenticator.authenticate(clientId, clientSecret, realm.id) : void 0;
45
+ const certificateEvidence = await extractOAuth2ClientCertificateEvidence(event, this.certificateSource);
46
+ const client = clientId ? await this.clientAuthenticator.authenticate(clientId, clientSecret, realm.id, certificateEvidence) : void 0;
47
+ const confirmation = client ? this.clientAuthenticator.resolveTokenBinding(client, certificateEvidence) : void 0;
32
48
  if (client) assertClientGrantAllowed(client, OAuth2TokenGrant.PASSWORD);
33
- const user = await this.authenticator.authenticate(username, password, realm.id);
49
+ const ipAddress = getRequestIP(event, { trustProxy: true }) ?? void 0;
50
+ const userAgent = getRequestHeader(event, "user-agent") ?? void 0;
51
+ const identifier = username.trim().toLowerCase();
52
+ await this.loginThrottleService?.assertNotThrottled({
53
+ identifier,
54
+ ipAddress,
55
+ realmId: realm.id
56
+ });
57
+ let user;
58
+ try {
59
+ user = await this.authenticator.authenticate(username, password, realm.id);
60
+ } catch (e) {
61
+ if (isEntityCredentialsInvalidError(e) || isEntityInactiveError(e)) {
62
+ await this.eventService?.record({
63
+ scope: EventScope.OAUTH2,
64
+ name: EventName.LOGIN_FAILED,
65
+ actorType: null,
66
+ actorId: null,
67
+ actorName: identifier,
68
+ clientId: client?.id ?? null,
69
+ realmId: realm.id,
70
+ requestIpAddress: ipAddress ?? null,
71
+ requestUserAgent: userAgent ?? null,
72
+ requestPath: event.path,
73
+ requestMethod: event.method,
74
+ data: { error_code: e.code }
75
+ });
76
+ this.metrics?.recordLogin("failure");
77
+ }
78
+ throw e;
79
+ }
80
+ const mfaVerifiedAt = await this.verifySecondFactor(user, body, {
81
+ ipAddress,
82
+ userAgent,
83
+ clientId: client?.id ?? null,
84
+ confirmation
85
+ });
34
86
  return this.runWith({
35
87
  user,
36
- client
88
+ client,
89
+ mfaVerifiedAt
90
+ }, {
91
+ confirmation,
92
+ ipAddress,
93
+ userAgent
94
+ });
95
+ }
96
+ /**
97
+ * MFA gate on the direct password grant: a user holding a confirmed
98
+ * device must send a valid `otp` form parameter (TOTP or recovery
99
+ * code, classified by shape) — otherwise `mfa_required`. Users
100
+ * without a device pass through (they could never enroll otherwise).
101
+ */ async verifySecondFactor(user, body, ctx) {
102
+ if (!this.userAuthenticatorService) return;
103
+ const status = await this.userAuthenticatorService.challenge(user.id, { issueMaterial: false });
104
+ if (!status.required) return;
105
+ const otp = readStringField(body, "otp");
106
+ if (!otp) {
107
+ const ticket = await this.issueMfaTicket(user, status.kinds, ctx);
108
+ throw new OAuth2MfaRequiredError({
109
+ message: "Complete a second-factor challenge to continue.",
110
+ data: {
111
+ kinds: status.kinds,
112
+ ...ticket ? {
113
+ mfa_token: ticket.token,
114
+ mfa_token_expires_in: ticket.expiresIn
115
+ } : {}
116
+ }
117
+ });
118
+ }
119
+ if (!await this.userAuthenticatorService.verify(user.id, {
120
+ kind: guessUserAuthenticatorKindByResponse(otp),
121
+ response: otp
37
122
  }, {
38
- ipAddress: getRequestIP(event, { trustProxy: true }) ?? void 0,
39
- userAgent: getRequestHeader(event, "user-agent") ?? void 0
123
+ ipAddress: ctx.ipAddress ?? null,
124
+ userAgent: ctx.userAgent ?? null,
125
+ clientId: ctx.clientId
126
+ })) throw new OAuth2MfaRequiredError({
127
+ message: "The provided second factor is not valid.",
128
+ data: { kinds: status.kinds }
40
129
  });
130
+ return (/* @__PURE__ */ new Date()).toISOString();
131
+ }
132
+ /**
133
+ * Issue the MFA-pending ticket for factor kinds that cannot complete
134
+ * inside the single grant POST (email needs a server-sent code,
135
+ * WebAuthn an interactive ceremony). TOTP/recovery-only users keep
136
+ * the inline `otp` fast-path and get no ticket — a pending session
137
+ * per plain code entry would be pure churn.
138
+ */ async issueMfaTicket(user, kinds, ctx) {
139
+ if (!this.mfaLoginService) return null;
140
+ if (!(kinds.includes(UserAuthenticatorKind.EMAIL) || kinds.includes(UserAuthenticatorKind.WEBAUTHN))) return null;
141
+ try {
142
+ return await this.mfaLoginService.issueTicket({
143
+ user,
144
+ clientId: ctx.clientId,
145
+ confirmation: ctx.confirmation
146
+ }, {
147
+ ipAddress: ctx.ipAddress,
148
+ userAgent: ctx.userAgent
149
+ });
150
+ } catch (e) {
151
+ this.logger?.warn("Issuing the MFA-pending login ticket failed.", { error: e });
152
+ return null;
153
+ }
41
154
  }
42
155
  };
43
156
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"password.mjs","names":["OAuth2RequestError","OAuth2TokenGrant","readRequestBody","getRequestHeader","getRequestIP","PasswordGrantType","assertClientGrantAllowed","extractClientCredentialsFromRequest","readRealmHint","readStringField","HTTPPasswordGrant","authenticator","clientAuthenticator","realmRepository","ctx","runWithRequest","event","body","username","password","malformed","clientId","clientSecret","realm","resolve","client","authenticate","id","undefined","PASSWORD","user","runWith","ipAddress","trustProxy","userAgent"],"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 type { OAuth2TokenGrantResponse } from '@authup/specs';\nimport { OAuth2RequestError, OAuth2TokenGrant } from '@authup/specs';\nimport { readRequestBody } from '@routup/basic/body';\nimport type { IAppEvent } from 'routup';\nimport { getRequestHeader, getRequestIP } from 'routup';\nimport type { ICredentialsAuthenticator, IRealmRepository, OAuth2ClientAuthenticator } from '../../../../../core/index.ts';\nimport { PasswordGrantType, assertClientGrantAllowed } from '../../../../../core/index.ts';\nimport type { HTTPOAuth2PasswordGrantContext, IHTTPOAuth2Grant } from './types.ts';\nimport { extractClientCredentialsFromRequest, readRealmHint, readStringField } 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 constructor(ctx: HTTPOAuth2PasswordGrantContext) {\n super(ctx);\n\n this.authenticator = ctx.authenticator;\n this.clientAuthenticator = ctx.clientAuthenticator;\n this.realmRepository = ctx.realmRepository;\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\n const client = clientId ?\n await this.clientAuthenticator.authenticate(\n clientId,\n clientSecret,\n realm.id,\n ) :\n undefined;\n\n if (client) {\n assertClientGrantAllowed(client, OAuth2TokenGrant.PASSWORD);\n }\n\n const user = await this.authenticator.authenticate(username, password, realm.id);\n\n return this.runWith(\n { user, client },\n {\n ipAddress: getRequestIP(event, { trustProxy: true }) ?? undefined,\n userAgent: getRequestHeader(event, 'user-agent') ?? undefined,\n },\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAkBA,IAAaU,oBAAb,cAAuCL,kBAAAA;CACzBM;CAEAC;CAEAC;CAEV,YAAYC,KAAqC;EAC7C,MAAMA,GAAAA;EAEN,KAAKH,gBAAgBG,IAAIH;EACzB,KAAKC,sBAAsBE,IAAIF;EAC/B,KAAKC,kBAAkBC,IAAID;CAC/B;CAEA,MAAME,eAAeC,OAAqD;EACtE,MAAMC,OAAO,MAAMf,gBAAgBc,KAAAA;EAEnC,MAAME,WAAWT,gBAAgBQ,MAAM,UAAA;EACvC,MAAME,WAAWV,gBAAgBQ,MAAM,UAAA;EACvC,IAAI,CAACC,YAAY,CAACC,UACd,MAAMnB,mBAAmBoB,UAAU,yCAAA;EAGvC,MAAM,EAAEC,UAAUC,iBAAiB,MAAMf,oCAAoCS,KAAAA;EAE7E,MAAMO,QAAQ,MAAM,KAAKV,gBAAgBW,QAAQhB,cAAcS,IAAAA,GAAO,IAAA;EAEtE,MAAMQ,SAASJ,WACX,MAAM,KAAKT,oBAAoBc,aAC3BL,UACAC,cACAC,MAAMI,EAAE,IAEZC,KAAAA;EAEJ,IAAIH,QACAnB,yBAAyBmB,QAAQxB,iBAAiB4B,QAAQ;EAG9D,MAAMC,OAAO,MAAM,KAAKnB,cAAce,aAAaR,UAAUC,UAAUI,MAAMI,EAAE;EAE/E,OAAO,KAAKI,QACR;GAAED;GAAML;EAAO,GACf;GACIO,WAAW5B,aAAaY,OAAO,EAAEiB,YAAY,KAAK,CAAA,KAAML,KAAAA;GACxDM,WAAW/B,iBAAiBa,OAAO,YAAA,KAAiBY,KAAAA;EACxD,CAAA;CAER;AACJ"}
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","error_code","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 actor_name 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: { error_code: 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":";;;;;;;;;;;;;;;;;AAsCA,IAAakB,oBAAb,cAAuCP,kBAAAA;CACzBQ;CAEAC;CAEAC;CAEAC;CAEAC;CAEAC;CAEAC;CAEAC;CAEV,YAAYC,KAAqC;EAC7C,MAAMA,GAAAA;EAEN,KAAKR,gBAAgBQ,IAAIR;EACzB,KAAKC,sBAAsBO,IAAIP;EAC/B,KAAKC,kBAAkBM,IAAIN;EAC3B,KAAKC,uBAAuBK,IAAIL;EAChC,KAAKC,2BAA2BI,IAAIJ;EACpC,KAAKC,kBAAkBG,IAAIH;EAC3B,KAAKC,SAASE,IAAIF;EAClB,KAAKC,oBAAoBC,IAAID,qBAAqB;CACtD;CAEA,MAAME,eAAeC,OAAqD;EACtE,MAAMC,OAAO,MAAMtB,gBAAgBqB,KAAAA;EAEnC,MAAME,WAAWd,gBAAgBa,MAAM,UAAA;EACvC,MAAME,WAAWf,gBAAgBa,MAAM,UAAA;EACvC,IAAI,CAACC,YAAY,CAACC,UACd,MAAM1B,mBAAmB2B,UAAU,yCAAA;EAGvC,MAAM,EAAEC,UAAUC,iBAAiB,MAAMrB,oCAAoCe,KAAAA;EAE7E,MAAMO,QAAQ,MAAM,KAAKf,gBAAgBgB,QAAQrB,cAAcc,IAAAA,GAAO,IAAA;EACtE,MAAMQ,sBAAsB,MAAMvB,uCAAuCc,OAAO,KAAKH,iBAAiB;EAEtG,MAAMa,SAASL,WACX,MAAM,KAAKd,oBAAoBoB,aAC3BN,UACAC,cACAC,MAAMK,IACNH,mBAAAA,IAEJI,KAAAA;EAEJ,MAAMC,eAAeJ,SACjB,KAAKnB,oBAAoBwB,oBAAoBL,QAAQD,mBAAAA,IACrDI,KAAAA;EAEJ,IAAIH,QACA3B,yBAAyB2B,QAAQhC,iBAAiBsC,QAAQ;EAG9D,MAAMC,YAAYpC,aAAamB,OAAO,EAAEkB,YAAY,KAAK,CAAA,KAAML,KAAAA;EAC/D,MAAMM,YAAYvC,iBAAiBoB,OAAO,YAAA,KAAiBa,KAAAA;EAI3D,MAAMO,aAAalB,SAASmB,KAAI,CAAA,CAAGC,YAAW;EAE9C,MAAM,KAAK7B,sBAAsB8B,mBAAmB;GAChDH;GACAH;GACAO,SAASjB,MAAMK;EACnB,CAAA;EAEA,IAAIa;EACJ,IAAI;GACAA,OAAO,MAAM,KAAKnC,cAAcqB,aAAaT,UAAUC,UAAUI,MAAMK,EAAE;EAC7E,SAASc,GAAG;GACR,IAAIpD,gCAAgCoD,CAAAA,KAAMnD,sBAAsBmD,CAAAA,GAAI;IAChE,MAAM,KAAKC,cAAcC,OAAO;KAC5BC,OAAOzD,WAAW0D;KAClBC,MAAM5D,UAAU6D;KAChBC,WAAW;KACXC,SAAS;KACTC,WAAWf;KACXf,UAAUK,QAAQE,MAAM;KACxBY,SAASjB,MAAMK;KACfwB,kBAAkBnB,aAAa;KAC/BoB,kBAAkBlB,aAAa;KAC/BmB,aAAatC,MAAMuC;KACnBC,eAAexC,MAAMyC;KACrBC,MAAM,EAAEC,YAAYjB,EAAEkB,KAAK;IAC/B,CAAA;IACA,KAAKC,SAASC,YAAY,SAAA;GAC9B;GAEA,MAAMpB;EACV;EAEA,MAAMqB,gBAAgB,MAAM,KAAKC,mBAAmBvB,MAAMxB,MAAM;GAC5DgB;GACAE;GACAd,UAAUK,QAAQE,MAAM;GACxBE;EACJ,CAAA;EAEA,OAAO,KAAKmC,QACR;GACIxB;GACAf;GACAqC;EACJ,GACA;GACIjC;GACAG;GACAE;EACJ,CAAA;CAER;;;;;;IAQA,MAAgB6B,mBACZvB,MACAxB,MACAH,KAM2B;EAC3B,IAAI,CAAC,KAAKJ,0BACN;EAIJ,MAAMwD,SAAS,MAAM,KAAKxD,yBAAyByD,UAAU1B,KAAKb,IAAI,EAAEwC,eAAe,MAAM,CAAA;EAC7F,IAAI,CAACF,OAAOG,UACR;EAGJ,MAAMC,MAAMlE,gBAAgBa,MAAM,KAAA;EAClC,IAAI,CAACqD,KAAK;GAQN,MAAMC,SAAS,MAAM,KAAKC,eAAe/B,MAAMyB,OAAOO,OAAO3D,GAAAA;GAE7D,MAAM,IAAItB,uBAAuB;IAC7BkF,SAAS;IACThB,MAAM;KACFe,OAAOP,OAAOO;KACd,GAAIF,SAAS;MACTI,WAAWJ,OAAOK;MAClBC,sBAAsBN,OAAOO;KACjC,IAAI,CAAC;IACT;GACJ,CAAA;EACJ;EAcA,IAAI,CAACC,MAZkB,KAAKrE,yBAAyBsE,OACjDvC,KAAKb,IACL;GACIqD,MAAMjF,qCAAqCsE,GAAAA;GAC3CY,UAAUZ;EACd,GACA;GACIrC,WAAWnB,IAAImB,aAAa;GAC5BE,WAAWrB,IAAIqB,aAAa;GAC5Bd,UAAUP,IAAIO;EAClB,CAAA,GAGA,MAAM,IAAI7B,uBAAuB;GAC7BkF,SAAS;GACThB,MAAM,EAAEe,OAAOP,OAAOO,MAAM;EAChC,CAAA;EAGJ,wBAAO,IAAIU,KAAAA,EAAAA,CAAOC,YAAW;CACjC;;;;;;;IASA,MAAgBZ,eACZ/B,MACAgC,OACA3D,KAMqD;EACrD,IAAI,CAAC,KAAKH,iBACN,OAAO;EAKX,IAAI,EAFgB8D,MAAMa,SAASjG,sBAAsBkG,KAAK,KAC1Dd,MAAMa,SAASjG,sBAAsBmG,QAAQ,IAE7C,OAAO;EAGX,IAAI;GACA,OAAO,MAAM,KAAK7E,gBAAgB8E,YAC9B;IACIhD;IACApB,UAAUP,IAAIO;IACdS,cAAchB,IAAIgB;GACtB,GACA;IACIG,WAAWnB,IAAImB;IACfE,WAAWrB,IAAIqB;GACnB,CAAA;EAER,SAASO,GAAG;GAMR,KAAK9B,QAAQ8E,KAAK,gDAAgD,EAAEC,OAAOjD,EAAE,CAAA;GAE7E,OAAO;EACX;CACJ;AACJ"}
@@ -3,10 +3,12 @@ import type { IAppEvent } from 'routup';
3
3
  import { OAuth2RefreshTokenGrant } from '../../../../../core/index.ts';
4
4
  import type { IOAuth2TokenVerifier, IRealmRepository, OAuth2ClientAuthenticator } from '../../../../../core/index.ts';
5
5
  import type { HTTPOAuth2RefreshTokenGrantContext, IHTTPOAuth2Grant } from './types.ts';
6
+ import type { CertificateSource } from '../../../request/index.ts';
6
7
  export declare class HTTPOAuth2RefreshTokenGrant extends OAuth2RefreshTokenGrant implements IHTTPOAuth2Grant {
7
8
  protected clientAuthenticator: OAuth2ClientAuthenticator;
8
9
  protected refreshTokenVerifier: IOAuth2TokenVerifier;
9
10
  protected realmRepository: IRealmRepository;
11
+ protected certificateSource: CertificateSource;
10
12
  constructor(ctx: HTTPOAuth2RefreshTokenGrantContext);
11
13
  runWithRequest(event: IAppEvent): Promise<OAuth2TokenGrantResponse>;
12
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"refresh_token.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/refresh_token.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAG9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAE,uBAAuB,EAA4B,MAAM,8BAA8B,CAAC;AACjG,OAAO,KAAK,EACR,oBAAoB,EACpB,gBAAgB,EAChB,yBAAyB,EAC5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,kCAAkC,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGvF,qBAAa,2BAA4B,SAAQ,uBAAwB,YAAW,gBAAgB;IAChG,SAAS,CAAC,mBAAmB,EAAG,yBAAyB,CAAC;IAE1D,SAAS,CAAC,oBAAoB,EAAG,oBAAoB,CAAC;IAEtD,SAAS,CAAC,eAAe,EAAG,gBAAgB,CAAC;gBAEjC,GAAG,EAAE,kCAAkC;IAQ7C,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,wBAAwB,CAAC;CA2E5E"}
1
+ {"version":3,"file":"refresh_token.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/adapters/oauth2/grant-types/refresh_token.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAA2B,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAGvF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAE,uBAAuB,EAA4B,MAAM,8BAA8B,CAAC;AACjG,OAAO,KAAK,EACR,oBAAoB,EACpB,gBAAgB,EAChB,yBAAyB,EAC5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,kCAAkC,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACvF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAOnE,qBAAa,2BAA4B,SAAQ,uBAAwB,YAAW,gBAAgB;IAChG,SAAS,CAAC,mBAAmB,EAAG,yBAAyB,CAAC;IAE1D,SAAS,CAAC,oBAAoB,EAAG,oBAAoB,CAAC;IAEtD,SAAS,CAAC,eAAe,EAAG,gBAAgB,CAAC;IAE7C,SAAS,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;gBAEnC,GAAG,EAAE,kCAAkC;IAS7C,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,wBAAwB,CAAC;CAqG5E"}
@@ -4,9 +4,11 @@ import.meta.url;
4
4
  import { assertClientGrantAllowed } from "../../../../../core/oauth2/client/grant-type.mjs";
5
5
  import { OAuth2RefreshTokenGrant } from "../../../../../core/oauth2/grant-types/refresh-token.mjs";
6
6
  import "../../../../../core/index.mjs";
7
+ import { extractOAuth2ClientCertificateEvidence } from "./utils/certificate.mjs";
7
8
  import { extractClientCredentialsFromRequest } from "./utils/credentials.mjs";
8
9
  import { readRealmHint } from "./utils/realm.mjs";
9
10
  import "./utils/index.mjs";
11
+ import { isClientPublic } from "@authup/core-kit";
10
12
  import { OAuth2GrantError, OAuth2RequestError, OAuth2TokenGrant } from "@authup/specs";
11
13
  import { getRequestHeader, getRequestIP } from "routup";
12
14
  import { readRequestBody } from "@routup/basic/body";
@@ -15,27 +17,38 @@ var HTTPOAuth2RefreshTokenGrant = class extends OAuth2RefreshTokenGrant {
15
17
  clientAuthenticator;
16
18
  refreshTokenVerifier;
17
19
  realmRepository;
20
+ certificateSource;
18
21
  constructor(ctx) {
19
22
  super(ctx);
20
23
  this.clientAuthenticator = ctx.clientAuthenticator;
21
24
  this.refreshTokenVerifier = ctx.tokenVerifier;
22
25
  this.realmRepository = ctx.realmRepository;
26
+ this.certificateSource = ctx.certificateSource ?? "disabled";
23
27
  }
24
28
  async runWithRequest(event) {
25
29
  const body = await readRequestBody(event);
26
30
  const refreshToken = body?.refresh_token;
27
31
  if (typeof refreshToken !== "string" || refreshToken.length === 0) throw OAuth2RequestError.malformed();
28
32
  const { clientId, clientSecret } = await extractClientCredentialsFromRequest(event);
33
+ const certificateEvidence = await extractOAuth2ClientCertificateEvidence(event, this.certificateSource);
29
34
  const payload = await this.refreshTokenVerifier.verify(refreshToken, { skipActiveCheck: true });
30
35
  let client;
31
36
  if (clientId) {
32
37
  const realm = await this.realmRepository.resolve(readRealmHint(body), true);
33
- client = await this.clientAuthenticator.authenticate(clientId, clientSecret, realm.id);
38
+ client = await this.clientAuthenticator.authenticate(clientId, clientSecret, realm.id, certificateEvidence);
34
39
  if (payload.client_id && payload.client_id !== client.id) throw OAuth2GrantError.invalid();
35
- } else if (payload.client_id) client = await this.clientAuthenticator.authenticate(payload.client_id);
40
+ } else if (payload.client_id) client = await this.clientAuthenticator.authenticate(payload.client_id, void 0, void 0, certificateEvidence);
36
41
  if (client) assertClientGrantAllowed(client, OAuth2TokenGrant.REFRESH_TOKEN);
37
- if (client && !client.is_confidential && payload.realm_id && payload.realm_id !== client.realm_id) throw OAuth2GrantError.invalid();
42
+ let confirmation;
43
+ if (payload.cnf) {
44
+ const expectedThumbprint = payload.cnf["x5t#S256"];
45
+ if (typeof expectedThumbprint !== "string" || expectedThumbprint.length === 0) throw OAuth2GrantError.invalid();
46
+ confirmation = this.clientAuthenticator.validateCertificateEvidenceForBinding(certificateEvidence);
47
+ if (confirmation["x5t#S256"] !== expectedThumbprint) throw OAuth2GrantError.invalid();
48
+ } else if (client) confirmation = this.clientAuthenticator.resolveTokenBinding(client, certificateEvidence);
49
+ if (client && isClientPublic(client) && payload.realm_id && payload.realm_id !== client.realm_id) throw OAuth2GrantError.invalid();
38
50
  return this.runWith(payload, {
51
+ confirmation,
39
52
  ipAddress: getRequestIP(event, { trustProxy: true }) ?? void 0,
40
53
  userAgent: getRequestHeader(event, "user-agent") ?? void 0
41
54
  });
@@ -1 +1 @@
1
- {"version":3,"file":"refresh_token.mjs","names":["OAuth2GrantError","OAuth2RequestError","OAuth2TokenGrant","readRequestBody","getRequestHeader","getRequestIP","OAuth2RefreshTokenGrant","assertClientGrantAllowed","extractClientCredentialsFromRequest","readRealmHint","HTTPOAuth2RefreshTokenGrant","clientAuthenticator","refreshTokenVerifier","realmRepository","ctx","tokenVerifier","runWithRequest","event","body","refreshToken","refresh_token","length","malformed","clientId","clientSecret","payload","verify","skipActiveCheck","client","realm","resolve","authenticate","id","client_id","invalid","REFRESH_TOKEN","is_confidential","realm_id","runWith","ipAddress","trustProxy","undefined","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 } from '@authup/core-kit';\nimport type { 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 { extractClientCredentialsFromRequest, readRealmHint } 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 constructor(ctx: HTTPOAuth2RefreshTokenGrantContext) {\n super(ctx);\n\n this.clientAuthenticator = ctx.clientAuthenticator;\n this.refreshTokenVerifier = ctx.tokenVerifier;\n this.realmRepository = ctx.realmRepository;\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\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 );\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 confidential client MUST still authenticate: authenticate()\n // with no secret throws invalid_client for it, so a confidential-\n // bound token presented without credentials is rejected here.\n client = await this.clientAuthenticator.authenticate(payload.client_id);\n }\n\n if (client) {\n assertClientGrantAllowed(client, OAuth2TokenGrant.REFRESH_TOKEN);\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. Confidential clients\n // are exempt — the client secret already 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 !client.is_confidential &&\n payload.realm_id &&\n payload.realm_id !== client.realm_id\n ) {\n throw OAuth2GrantError.invalid();\n }\n\n return this.runWith(payload, {\n ipAddress: getRequestIP(event, { trustProxy: true }) ?? undefined,\n userAgent: getRequestHeader(event, 'user-agent') ?? undefined,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAsBA,IAAaU,8BAAb,cAAiDJ,wBAAAA;CACnCK;CAEAC;CAEAC;CAEV,YAAYC,KAAyC;EACjD,MAAMA,GAAAA;EAEN,KAAKH,sBAAsBG,IAAIH;EAC/B,KAAKC,uBAAuBE,IAAIC;EAChC,KAAKF,kBAAkBC,IAAID;CAC/B;CAEA,MAAMG,eAAeC,OAAqD;EACtE,MAAMC,OAAO,MAAMf,gBAAgBc,KAAAA;EACnC,MAAME,eAAeD,MAAME;EAC3B,IAAI,OAAOD,iBAAiB,YAAYA,aAAaE,WAAW,GAC5D,MAAMpB,mBAAmBqB,UAAS;EAGtC,MAAM,EAAEC,UAAUC,iBAAiB,MAAMhB,oCAAoCS,KAAAA;EAW7E,MAAMQ,UAAU,MAAM,KAAKb,qBAAqBc,OAAOP,cAAc,EAAEQ,iBAAiB,KAAK,CAAA;EAE7F,IAAIC;EAEJ,IAAIL,UAAU;GAKV,MAAMM,QAAQ,MAAM,KAAKhB,gBAAgBiB,QAAQrB,cAAcS,IAAAA,GAAO,IAAA;GAEtEU,SAAS,MAAM,KAAKjB,oBAAoBoB,aACpCR,UACAC,cACAK,MAAMG,EAAE;GAGZ,IAAIP,QAAQQ,aAAaR,QAAQQ,cAAcL,OAAOI,IAClD,MAAMhC,iBAAiBkC,QAAO;EAEtC,OAAO,IAAIT,QAAQQ,WASfL,SAAS,MAAM,KAAKjB,oBAAoBoB,aAAaN,QAAQQ,SAAS;EAG1E,IAAIL,QACArB,yBAAyBqB,QAAQ1B,iBAAiBiC,aAAa;EAUnE,IACIP,UACA,CAACA,OAAOQ,mBACRX,QAAQY,YACRZ,QAAQY,aAAaT,OAAOS,UAE5B,MAAMrC,iBAAiBkC,QAAO;EAGlC,OAAO,KAAKI,QAAQb,SAAS;GACzBc,WAAWlC,aAAaY,OAAO,EAAEuB,YAAY,KAAK,CAAA,KAAMC,KAAAA;GACxDC,WAAWtC,iBAAiBa,OAAO,YAAA,KAAiBwB,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","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.realm_id\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,OAAOc,UAE5B,MAAM7C,iBAAiBqC,QAAO;EAGlC,OAAO,KAAKS,QAAQlB,SAAS;GACzBY;GACAO,WAAW1C,aAAac,OAAO,EAAE6B,YAAY,KAAK,CAAA,KAAMV,KAAAA;GACxDW,WAAW7C,iBAAiBe,OAAO,YAAA,KAAiBmB,KAAAA;EACxD,CAAA;CACJ;AACJ"}