@udibo/oauth2 0.14.1 → 0.15.1

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 (413) hide show
  1. package/README.md +45 -24
  2. package/{esm → dist}/adapters/hono/_common.d.ts +5 -5
  3. package/{esm → dist}/adapters/hono/_common.js +1 -1
  4. package/{esm → dist}/adapters/hono/authorization-server.d.ts +6 -7
  5. package/{esm → dist}/adapters/hono/authorization-server.js +0 -1
  6. package/{esm → dist}/adapters/hono/bff/auth-request-store.d.ts +2 -2
  7. package/{esm → dist}/adapters/hono/bff/auth-request-store.js +2 -2
  8. package/{esm → dist}/adapters/hono/bff/bff.d.ts +8 -8
  9. package/{esm → dist}/adapters/hono/bff/bff.js +33 -27
  10. package/{esm → dist}/adapters/hono/bff/cookie-prefix.js +1 -2
  11. package/{esm → dist}/adapters/hono/bff/mod.d.ts +5 -6
  12. package/{esm → dist}/adapters/hono/bff/mod.js +1 -2
  13. package/{esm → dist}/adapters/hono/bff/proxy.js +2 -1
  14. package/{esm → dist}/adapters/hono/bff/session-store.d.ts +2 -2
  15. package/{esm → dist}/adapters/hono/bff/session-store.js +7 -6
  16. package/{esm → dist}/adapters/hono/bff/testing.d.ts +7 -8
  17. package/{esm → dist}/adapters/hono/bff/testing.js +19 -22
  18. package/{esm → dist}/adapters/hono/identity.d.ts +1 -2
  19. package/{esm → dist}/adapters/hono/identity.js +10 -10
  20. package/{esm → dist}/adapters/hono/log.d.ts +0 -1
  21. package/{esm → dist}/adapters/hono/log.js +0 -6
  22. package/{esm → dist}/adapters/hono/resource-server.d.ts +5 -6
  23. package/{esm → dist}/adapters/hono/resource-server.js +0 -1
  24. package/dist/cli/bin.d.ts +2 -0
  25. package/dist/cli/bin.js +3 -0
  26. package/dist/cli/idp/config.d.ts +110 -0
  27. package/dist/cli/idp/config.js +269 -0
  28. package/dist/cli/idp/mod.d.ts +20 -0
  29. package/dist/cli/idp/mod.js +175 -0
  30. package/dist/cli/idp/pages.d.ts +56 -0
  31. package/dist/cli/idp/pages.js +190 -0
  32. package/dist/cli/idp/server.d.ts +93 -0
  33. package/dist/cli/idp/server.js +559 -0
  34. package/dist/cli/keygen.d.ts +13 -0
  35. package/dist/cli/keygen.js +30 -0
  36. package/dist/cli/mod.d.ts +34 -0
  37. package/dist/cli/mod.js +94 -0
  38. package/{esm → dist}/client/_http.d.ts +1 -1
  39. package/{esm → dist}/client/base.d.ts +1 -1
  40. package/{esm → dist}/client/bff-client.d.ts +1 -1
  41. package/{esm → dist}/client/bff-client.js +7 -6
  42. package/{esm → dist}/client/browser-storage.d.ts +1 -1
  43. package/{esm → dist}/client/check.js +1 -1
  44. package/{esm → dist}/client/direct-client.d.ts +6 -6
  45. package/{esm → dist}/client/direct-client.js +11 -13
  46. package/{esm → dist}/client/discovery-cache.d.ts +1 -1
  47. package/{esm → dist}/client/discovery-cache.js +2 -2
  48. package/{esm → dist}/client/events.d.ts +1 -1
  49. package/{esm → dist}/client/mod.d.ts +11 -12
  50. package/{esm → dist}/client/mod.js +1 -1
  51. package/{esm → dist}/errors.d.ts +1 -1
  52. package/{esm → dist}/errors.js +1 -1
  53. package/{esm → dist}/identity/events.d.ts +1 -1
  54. package/{esm → dist}/identity/external/_shared.d.ts +1 -1
  55. package/{esm → dist}/identity/external/_shared.js +1 -2
  56. package/{esm → dist}/identity/external/apple-client-secret.d.ts +1 -1
  57. package/{esm → dist}/identity/external/apple-client-secret.js +6 -7
  58. package/{esm → dist}/identity/external/apple.d.ts +5 -5
  59. package/{esm → dist}/identity/external/apple.js +10 -11
  60. package/{esm → dist}/identity/external/discord.d.ts +3 -3
  61. package/{esm → dist}/identity/external/discord.js +2 -2
  62. package/{esm → dist}/identity/external/flow.d.ts +1 -1
  63. package/{esm → dist}/identity/external/flow.js +2 -2
  64. package/{esm → dist}/identity/external/github.d.ts +3 -3
  65. package/{esm → dist}/identity/external/github.js +12 -17
  66. package/{esm → dist}/identity/external/google.d.ts +5 -5
  67. package/{esm → dist}/identity/external/google.js +2 -2
  68. package/{esm → dist}/identity/external/mod.d.ts +12 -13
  69. package/{esm → dist}/identity/external/mod.js +0 -1
  70. package/{esm → dist}/identity/external/oauth2.d.ts +1 -1
  71. package/{esm → dist}/identity/external/oauth2.js +8 -8
  72. package/{esm → dist}/identity/external/oidc.d.ts +4 -4
  73. package/{esm → dist}/identity/external/oidc.js +9 -8
  74. package/{esm → dist}/identity/hibp.d.ts +1 -1
  75. package/{esm → dist}/identity/hibp.js +1 -1
  76. package/{esm → dist}/identity/lockout.js +1 -2
  77. package/{esm → dist}/identity/mfa/mod.d.ts +4 -5
  78. package/{esm → dist}/identity/mfa/mod.js +1 -2
  79. package/{esm → dist}/identity/mfa/service.d.ts +3 -3
  80. package/{esm → dist}/identity/mfa/service.js +4 -3
  81. package/{esm → dist}/identity/mfa/totp.d.ts +1 -1
  82. package/{esm → dist}/identity/mfa/totp.js +2 -2
  83. package/{esm → dist}/identity/migration.d.ts +2 -3
  84. package/{esm → dist}/identity/migration.js +3 -4
  85. package/{esm → dist}/identity/mod.d.ts +14 -15
  86. package/{esm → dist}/identity/mod.js +0 -1
  87. package/{esm → dist}/identity/otp.d.ts +1 -1
  88. package/{esm → dist}/identity/otp.js +4 -2
  89. package/{esm → dist}/identity/password.js +8 -5
  90. package/{esm → dist}/identity/rate-limit.d.ts +1 -1
  91. package/{esm → dist}/identity/service.d.ts +10 -10
  92. package/{esm → dist}/identity/service.js +17 -18
  93. package/{esm → dist}/identity/session.js +2 -2
  94. package/{esm → dist}/identity/token-flow.js +3 -2
  95. package/{esm → dist}/models/authorization-code.d.ts +3 -3
  96. package/{esm → dist}/models/authorization.d.ts +1 -1
  97. package/{esm → dist}/models/authorization.js +1 -2
  98. package/{esm → dist}/models/device-authorization.d.ts +2 -2
  99. package/{esm → dist}/models/token.d.ts +3 -3
  100. package/{esm → dist}/react/callback.d.ts +1 -1
  101. package/{esm → dist}/react/callback.js +0 -1
  102. package/{esm → dist}/react/components/class-names.d.ts +1 -1
  103. package/{esm → dist}/react/components/class-names.js +3 -2
  104. package/{esm → dist}/react/components/internal.d.ts +2 -2
  105. package/{esm → dist}/react/components/internal.js +5 -11
  106. package/{esm → dist}/react/components/mfa-challenge-form.d.ts +2 -2
  107. package/{esm → dist}/react/components/mfa-challenge-form.js +4 -6
  108. package/{esm → dist}/react/components/mfa-enrollment-form.d.ts +2 -2
  109. package/{esm → dist}/react/components/mfa-enrollment-form.js +2 -6
  110. package/{esm → dist}/react/components/mod.d.ts +20 -21
  111. package/{esm → dist}/react/components/mod.js +1 -2
  112. package/{esm → dist}/react/components/request-password-reset-form.d.ts +2 -2
  113. package/{esm → dist}/react/components/request-password-reset-form.js +1 -3
  114. package/{esm → dist}/react/components/reset-password-form.d.ts +2 -2
  115. package/{esm → dist}/react/components/reset-password-form.js +2 -2
  116. package/{esm → dist}/react/components/sign-in-form.d.ts +2 -2
  117. package/{esm → dist}/react/components/sign-in-form.js +1 -5
  118. package/{esm → dist}/react/components/sign-up-form.d.ts +2 -2
  119. package/{esm → dist}/react/components/sign-up-form.js +4 -10
  120. package/{esm → dist}/react/components/types.d.ts +2 -2
  121. package/{esm → dist}/react/components/use-auth-form.d.ts +3 -3
  122. package/{esm → dist}/react/components/use-auth-form.js +4 -7
  123. package/{esm → dist}/react/components/user-menu.d.ts +2 -2
  124. package/{esm → dist}/react/components/user-menu.js +9 -14
  125. package/{esm → dist}/react/context.d.ts +1 -1
  126. package/{esm → dist}/react/mod.d.ts +6 -7
  127. package/{esm → dist}/react/mod.js +0 -1
  128. package/{esm → dist}/react/provider.d.ts +2 -2
  129. package/{esm → dist}/react/require-auth.js +1 -3
  130. package/{esm → dist}/react/testing.d.ts +2 -3
  131. package/{esm → dist}/react/testing.js +1 -2
  132. package/{esm → dist}/react/use-authorization.d.ts +1 -1
  133. package/{esm → dist}/react/use-oauth2.d.ts +8 -1
  134. package/{esm → dist}/react/use-oauth2.js +0 -1
  135. package/{esm → dist}/server/_clock-skew.js +2 -1
  136. package/{esm → dist}/server/authorization-server.d.ts +40 -41
  137. package/{esm → dist}/server/authorization-server.js +32 -42
  138. package/{esm → dist}/server/client-authentication.d.ts +2 -2
  139. package/{esm → dist}/server/grants/authorization-code.d.ts +9 -9
  140. package/{esm → dist}/server/grants/authorization-code.js +5 -6
  141. package/{esm → dist}/server/grants/client-credentials.d.ts +4 -4
  142. package/{esm → dist}/server/grants/device-authorization.d.ts +6 -6
  143. package/{esm → dist}/server/grants/device-authorization.js +4 -4
  144. package/{esm → dist}/server/grants/grant.d.ts +7 -7
  145. package/{esm → dist}/server/grants/grant.js +7 -7
  146. package/{esm → dist}/server/grants/password.d.ts +5 -5
  147. package/{esm → dist}/server/grants/refresh-token.d.ts +4 -4
  148. package/{esm → dist}/server/grants/refresh-token.js +5 -6
  149. package/{esm → dist}/server/introspection-token-reader.d.ts +5 -5
  150. package/{esm → dist}/server/introspection-token-reader.js +4 -4
  151. package/{esm → dist}/server/jwks-token-reader.d.ts +5 -5
  152. package/{esm → dist}/server/jwks-token-reader.js +4 -4
  153. package/{esm → dist}/server/mod.d.ts +12 -13
  154. package/{esm → dist}/server/mod.js +0 -1
  155. package/{esm → dist}/server/public-suffix/mod.d.ts +2 -3
  156. package/{esm → dist}/server/public-suffix/mod.js +1 -2
  157. package/{esm → dist}/server/public-suffix/rules.d.ts +1 -1
  158. package/{esm → dist}/server/public-suffix/rules.js +1 -1
  159. package/{esm → dist}/server/redirect-uri.js +5 -4
  160. package/{esm → dist}/server/resource-server.d.ts +11 -12
  161. package/{esm → dist}/server/resource-server.js +12 -14
  162. package/{esm → dist}/server/services/authorization-code.d.ts +5 -5
  163. package/{esm → dist}/server/services/client.d.ts +1 -1
  164. package/{esm → dist}/server/services/device-authorization.d.ts +3 -3
  165. package/{esm → dist}/server/services/token.d.ts +6 -6
  166. package/{esm → dist}/server/services/token.js +3 -1
  167. package/{esm → dist}/server/services/user.d.ts +1 -1
  168. package/{esm → dist}/server/signing-keys.d.ts +1 -1
  169. package/{esm → dist}/server/signing-keys.js +8 -2
  170. package/{esm → dist}/server/utils/hash.js +1 -1
  171. package/{esm → dist}/testing/contract/auth-request-storage.d.ts +1 -1
  172. package/{esm → dist}/testing/contract/auth-request-storage.js +24 -29
  173. package/{esm → dist}/testing/contract/authorization-code.d.ts +6 -6
  174. package/{esm → dist}/testing/contract/authorization-code.js +16 -17
  175. package/{esm → dist}/testing/contract/client.d.ts +4 -4
  176. package/{esm → dist}/testing/contract/client.js +14 -15
  177. package/{esm → dist}/testing/contract/device-authorization.d.ts +6 -6
  178. package/{esm → dist}/testing/contract/device-authorization.js +37 -39
  179. package/{esm → dist}/testing/contract/identity-session.d.ts +6 -1
  180. package/{esm → dist}/testing/contract/identity-session.js +44 -36
  181. package/{esm → dist}/testing/contract/identity-user-store.d.ts +8 -2
  182. package/{esm → dist}/testing/contract/identity-user-store.js +48 -46
  183. package/{esm → dist}/testing/contract/lockout-store.d.ts +1 -1
  184. package/{esm → dist}/testing/contract/lockout-store.js +23 -24
  185. package/{esm → dist}/testing/contract/mfa-store.d.ts +1 -1
  186. package/{esm → dist}/testing/contract/mfa-store.js +53 -54
  187. package/{esm → dist}/testing/contract/mod.d.ts +15 -16
  188. package/{esm → dist}/testing/contract/mod.js +0 -1
  189. package/{esm → dist}/testing/contract/otp-store.d.ts +1 -1
  190. package/{esm → dist}/testing/contract/otp-store.js +33 -34
  191. package/{esm → dist}/testing/contract/rate-limit-store.d.ts +1 -1
  192. package/{esm → dist}/testing/contract/rate-limit-store.js +15 -16
  193. package/{esm → dist}/testing/contract/tenant.js +361 -330
  194. package/{esm → dist}/testing/contract/token-flow-store.d.ts +1 -1
  195. package/{esm → dist}/testing/contract/token-flow-store.js +27 -32
  196. package/{esm → dist}/testing/contract/token-reader.d.ts +3 -3
  197. package/{esm → dist}/testing/contract/token-reader.js +6 -7
  198. package/{esm → dist}/testing/contract/token.d.ts +7 -7
  199. package/{esm → dist}/testing/contract/token.js +48 -53
  200. package/{esm → dist}/testing/contract/user.d.ts +2 -2
  201. package/{esm → dist}/testing/contract/user.js +8 -9
  202. package/{esm → dist}/testing/mod.d.ts +5 -6
  203. package/{esm → dist}/testing/mod.js +2 -3
  204. package/{esm → dist}/testing/server.d.ts +7 -6
  205. package/{esm → dist}/testing/server.js +2 -1
  206. package/{esm → dist}/testing/services.d.ts +11 -11
  207. package/{esm → dist}/testing/services.js +8 -8
  208. package/{esm → dist}/testing/tenant.d.ts +11 -7
  209. package/{esm → dist}/testing/tenant.js +109 -94
  210. package/dist/utils/_constant-time.d.ts +12 -0
  211. package/dist/utils/_constant-time.js +19 -0
  212. package/{esm → dist}/utils/_default-fetch.js +4 -1
  213. package/dist/utils/_delay.d.ts +13 -0
  214. package/dist/utils/_delay.js +28 -0
  215. package/dist/utils/_encoding.d.ts +39 -0
  216. package/dist/utils/_encoding.js +126 -0
  217. package/dist/utils/_inbound-request.d.ts +15 -0
  218. package/dist/utils/_inbound-request.js +25 -0
  219. package/{esm → dist}/utils/authentication-context.d.ts +1 -1
  220. package/{esm → dist}/utils/crypto.d.ts +2 -3
  221. package/{esm → dist}/utils/crypto.js +3 -4
  222. package/{esm → dist}/utils/pkce.js +1 -1
  223. package/{esm → dist}/utils/text.js +1 -1
  224. package/{esm → dist}/utils/url.d.ts +0 -1
  225. package/{esm → dist}/utils/url.js +0 -1
  226. package/package.json +156 -33
  227. package/esm/_dnt.polyfills.d.ts +0 -31
  228. package/esm/_dnt.polyfills.js +0 -26
  229. package/esm/deps/jsr.io/@std/assert/1.0.19/almost_equals.d.ts +0 -29
  230. package/esm/deps/jsr.io/@std/assert/1.0.19/almost_equals.js +0 -47
  231. package/esm/deps/jsr.io/@std/assert/1.0.19/array_includes.d.ts +0 -28
  232. package/esm/deps/jsr.io/@std/assert/1.0.19/array_includes.js +0 -65
  233. package/esm/deps/jsr.io/@std/assert/1.0.19/assert.d.ts +0 -16
  234. package/esm/deps/jsr.io/@std/assert/1.0.19/assert.js +0 -23
  235. package/esm/deps/jsr.io/@std/assert/1.0.19/assertion_error.d.ts +0 -25
  236. package/esm/deps/jsr.io/@std/assert/1.0.19/assertion_error.js +0 -30
  237. package/esm/deps/jsr.io/@std/assert/1.0.19/equal.d.ts +0 -24
  238. package/esm/deps/jsr.io/@std/assert/1.0.19/equal.js +0 -193
  239. package/esm/deps/jsr.io/@std/assert/1.0.19/equals.d.ts +0 -36
  240. package/esm/deps/jsr.io/@std/assert/1.0.19/equals.js +0 -61
  241. package/esm/deps/jsr.io/@std/assert/1.0.19/exists.d.ts +0 -17
  242. package/esm/deps/jsr.io/@std/assert/1.0.19/exists.js +0 -27
  243. package/esm/deps/jsr.io/@std/assert/1.0.19/fail.d.ts +0 -14
  244. package/esm/deps/jsr.io/@std/assert/1.0.19/fail.js +0 -20
  245. package/esm/deps/jsr.io/@std/assert/1.0.19/false.d.ts +0 -18
  246. package/esm/deps/jsr.io/@std/assert/1.0.19/false.js +0 -23
  247. package/esm/deps/jsr.io/@std/assert/1.0.19/greater.d.ts +0 -19
  248. package/esm/deps/jsr.io/@std/assert/1.0.19/greater.js +0 -29
  249. package/esm/deps/jsr.io/@std/assert/1.0.19/greater_or_equal.d.ts +0 -19
  250. package/esm/deps/jsr.io/@std/assert/1.0.19/greater_or_equal.js +0 -29
  251. package/esm/deps/jsr.io/@std/assert/1.0.19/instance_of.d.ts +0 -22
  252. package/esm/deps/jsr.io/@std/assert/1.0.19/instance_of.js +0 -52
  253. package/esm/deps/jsr.io/@std/assert/1.0.19/is_error.d.ts +0 -24
  254. package/esm/deps/jsr.io/@std/assert/1.0.19/is_error.js +0 -53
  255. package/esm/deps/jsr.io/@std/assert/1.0.19/less.d.ts +0 -18
  256. package/esm/deps/jsr.io/@std/assert/1.0.19/less.js +0 -28
  257. package/esm/deps/jsr.io/@std/assert/1.0.19/less_or_equal.d.ts +0 -19
  258. package/esm/deps/jsr.io/@std/assert/1.0.19/less_or_equal.js +0 -29
  259. package/esm/deps/jsr.io/@std/assert/1.0.19/match.d.ts +0 -17
  260. package/esm/deps/jsr.io/@std/assert/1.0.19/match.js +0 -26
  261. package/esm/deps/jsr.io/@std/assert/1.0.19/mod.d.ts +0 -43
  262. package/esm/deps/jsr.io/@std/assert/1.0.19/mod.js +0 -45
  263. package/esm/deps/jsr.io/@std/assert/1.0.19/not_equals.d.ts +0 -26
  264. package/esm/deps/jsr.io/@std/assert/1.0.19/not_equals.js +0 -39
  265. package/esm/deps/jsr.io/@std/assert/1.0.19/not_instance_of.d.ts +0 -19
  266. package/esm/deps/jsr.io/@std/assert/1.0.19/not_instance_of.js +0 -29
  267. package/esm/deps/jsr.io/@std/assert/1.0.19/not_match.d.ts +0 -17
  268. package/esm/deps/jsr.io/@std/assert/1.0.19/not_match.js +0 -26
  269. package/esm/deps/jsr.io/@std/assert/1.0.19/not_strict_equals.d.ts +0 -22
  270. package/esm/deps/jsr.io/@std/assert/1.0.19/not_strict_equals.js +0 -32
  271. package/esm/deps/jsr.io/@std/assert/1.0.19/object_match.d.ts +0 -28
  272. package/esm/deps/jsr.io/@std/assert/1.0.19/object_match.js +0 -177
  273. package/esm/deps/jsr.io/@std/assert/1.0.19/rejects.d.ts +0 -41
  274. package/esm/deps/jsr.io/@std/assert/1.0.19/rejects.js +0 -53
  275. package/esm/deps/jsr.io/@std/assert/1.0.19/strict_equals.d.ts +0 -23
  276. package/esm/deps/jsr.io/@std/assert/1.0.19/strict_equals.js +0 -58
  277. package/esm/deps/jsr.io/@std/assert/1.0.19/string_includes.d.ts +0 -17
  278. package/esm/deps/jsr.io/@std/assert/1.0.19/string_includes.js +0 -26
  279. package/esm/deps/jsr.io/@std/assert/1.0.19/throws.d.ts +0 -44
  280. package/esm/deps/jsr.io/@std/assert/1.0.19/throws.js +0 -44
  281. package/esm/deps/jsr.io/@std/assert/1.0.19/unimplemented.d.ts +0 -14
  282. package/esm/deps/jsr.io/@std/assert/1.0.19/unimplemented.js +0 -20
  283. package/esm/deps/jsr.io/@std/assert/1.0.19/unreachable.d.ts +0 -14
  284. package/esm/deps/jsr.io/@std/assert/1.0.19/unreachable.js +0 -20
  285. package/esm/deps/jsr.io/@std/async/1.5.0/delay.d.ts +0 -44
  286. package/esm/deps/jsr.io/@std/async/1.5.0/delay.js +0 -84
  287. package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts +0 -39
  288. package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.js +0 -61
  289. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common16.d.ts +0 -22
  290. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common16.js +0 -51
  291. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common32.d.ts +0 -34
  292. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common32.js +0 -192
  293. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common64.d.ts +0 -34
  294. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common64.js +0 -113
  295. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common_detach.d.ts +0 -3
  296. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common_detach.js +0 -13
  297. package/esm/deps/jsr.io/@std/encoding/1.0.11/_types.d.ts +0 -8
  298. package/esm/deps/jsr.io/@std/encoding/1.0.11/_types.js +0 -2
  299. package/esm/deps/jsr.io/@std/encoding/1.0.11/_validate_binary_like.d.ts +0 -1
  300. package/esm/deps/jsr.io/@std/encoding/1.0.11/_validate_binary_like.js +0 -26
  301. package/esm/deps/jsr.io/@std/encoding/1.0.11/ascii85.d.ts +0 -60
  302. package/esm/deps/jsr.io/@std/encoding/1.0.11/ascii85.js +0 -152
  303. package/esm/deps/jsr.io/@std/encoding/1.0.11/base32.d.ts +0 -39
  304. package/esm/deps/jsr.io/@std/encoding/1.0.11/base32.js +0 -87
  305. package/esm/deps/jsr.io/@std/encoding/1.0.11/base58.d.ts +0 -39
  306. package/esm/deps/jsr.io/@std/encoding/1.0.11/base58.js +0 -131
  307. package/esm/deps/jsr.io/@std/encoding/1.0.11/base64.d.ts +0 -39
  308. package/esm/deps/jsr.io/@std/encoding/1.0.11/base64.js +0 -82
  309. package/esm/deps/jsr.io/@std/encoding/1.0.11/base64url.d.ts +0 -39
  310. package/esm/deps/jsr.io/@std/encoding/1.0.11/base64url.js +0 -72
  311. package/esm/deps/jsr.io/@std/encoding/1.0.11/hex.d.ts +0 -38
  312. package/esm/deps/jsr.io/@std/encoding/1.0.11/hex.js +0 -87
  313. package/esm/deps/jsr.io/@std/encoding/1.0.11/mod.d.ts +0 -97
  314. package/esm/deps/jsr.io/@std/encoding/1.0.11/mod.js +0 -99
  315. package/esm/deps/jsr.io/@std/encoding/1.0.11/varint.d.ts +0 -119
  316. package/esm/deps/jsr.io/@std/encoding/1.0.11/varint.js +0 -209
  317. package/esm/deps/jsr.io/@std/http/1.1.3/status.d.ts +0 -343
  318. package/esm/deps/jsr.io/@std/http/1.1.3/status.js +0 -343
  319. package/esm/deps/jsr.io/@std/internal/1.0.14/assertion_state.d.ts +0 -159
  320. package/esm/deps/jsr.io/@std/internal/1.0.14/assertion_state.js +0 -223
  321. package/esm/deps/jsr.io/@std/internal/1.0.14/build_message.d.ts +0 -79
  322. package/esm/deps/jsr.io/@std/internal/1.0.14/build_message.js +0 -116
  323. package/esm/deps/jsr.io/@std/internal/1.0.14/diff.d.ts +0 -139
  324. package/esm/deps/jsr.io/@std/internal/1.0.14/diff.js +0 -277
  325. package/esm/deps/jsr.io/@std/internal/1.0.14/diff_str.d.ts +0 -98
  326. package/esm/deps/jsr.io/@std/internal/1.0.14/diff_str.js +0 -181
  327. package/esm/deps/jsr.io/@std/internal/1.0.14/format.d.ts +0 -29
  328. package/esm/deps/jsr.io/@std/internal/1.0.14/format.js +0 -68
  329. package/esm/deps/jsr.io/@std/internal/1.0.14/styles.d.ts +0 -158
  330. package/esm/deps/jsr.io/@std/internal/1.0.14/styles.js +0 -206
  331. package/esm/deps/jsr.io/@std/internal/1.0.14/types.d.ts +0 -24
  332. package/esm/deps/jsr.io/@std/internal/1.0.14/types.js +0 -3
  333. package/esm/deps/jsr.io/@std/testing/1.0.20/_test_suite.d.ts +0 -91
  334. package/esm/deps/jsr.io/@std/testing/1.0.20/_test_suite.js +0 -347
  335. package/esm/deps/jsr.io/@std/testing/1.0.20/bdd.d.ts +0 -382
  336. package/esm/deps/jsr.io/@std/testing/1.0.20/bdd.js +0 -1110
  337. package/esm/deps/jsr.io/@udibo/http-error/0.11.1/mod.d.ts +0 -363
  338. package/esm/deps/jsr.io/@udibo/http-error/0.11.1/mod.js +0 -616
  339. package/esm/package.json +0 -3
  340. /package/{esm → dist}/adapters/hono/bff/cookie-prefix.d.ts +0 -0
  341. /package/{esm → dist}/adapters/hono/bff/proxy.d.ts +0 -0
  342. /package/{esm → dist}/client/_http.js +0 -0
  343. /package/{esm → dist}/client/base.js +0 -0
  344. /package/{esm → dist}/client/browser-storage.js +0 -0
  345. /package/{esm → dist}/client/check.d.ts +0 -0
  346. /package/{esm → dist}/client/events.js +0 -0
  347. /package/{esm → dist}/client/storage.d.ts +0 -0
  348. /package/{esm → dist}/client/storage.js +0 -0
  349. /package/{esm → dist}/identity/captcha.d.ts +0 -0
  350. /package/{esm → dist}/identity/captcha.js +0 -0
  351. /package/{esm → dist}/identity/delivery.d.ts +0 -0
  352. /package/{esm → dist}/identity/delivery.js +0 -0
  353. /package/{esm → dist}/identity/errors.d.ts +0 -0
  354. /package/{esm → dist}/identity/errors.js +0 -0
  355. /package/{esm → dist}/identity/events.js +0 -0
  356. /package/{esm → dist}/identity/external/_token-exchange.d.ts +0 -0
  357. /package/{esm → dist}/identity/external/_token-exchange.js +0 -0
  358. /package/{esm → dist}/identity/external/errors.d.ts +0 -0
  359. /package/{esm → dist}/identity/external/errors.js +0 -0
  360. /package/{esm → dist}/identity/external/provider.d.ts +0 -0
  361. /package/{esm → dist}/identity/external/provider.js +0 -0
  362. /package/{esm → dist}/identity/identifier.d.ts +0 -0
  363. /package/{esm → dist}/identity/identifier.js +0 -0
  364. /package/{esm → dist}/identity/lockout.d.ts +0 -0
  365. /package/{esm → dist}/identity/mfa/recovery-codes.d.ts +0 -0
  366. /package/{esm → dist}/identity/mfa/recovery-codes.js +0 -0
  367. /package/{esm → dist}/identity/password-policy.d.ts +0 -0
  368. /package/{esm → dist}/identity/password-policy.js +0 -0
  369. /package/{esm → dist}/identity/password.d.ts +0 -0
  370. /package/{esm → dist}/identity/rate-limit.js +0 -0
  371. /package/{esm → dist}/identity/session.d.ts +0 -0
  372. /package/{esm → dist}/identity/token-flow.d.ts +0 -0
  373. /package/{esm → dist}/models/authentication.d.ts +0 -0
  374. /package/{esm → dist}/models/authentication.js +0 -0
  375. /package/{esm → dist}/models/authorization-code.js +0 -0
  376. /package/{esm → dist}/models/client.d.ts +0 -0
  377. /package/{esm → dist}/models/client.js +0 -0
  378. /package/{esm → dist}/models/device-authorization.js +0 -0
  379. /package/{esm → dist}/models/responses.d.ts +0 -0
  380. /package/{esm → dist}/models/responses.js +0 -0
  381. /package/{esm → dist}/models/scope.d.ts +0 -0
  382. /package/{esm → dist}/models/scope.js +0 -0
  383. /package/{esm → dist}/models/token.js +0 -0
  384. /package/{esm → dist}/react/components/types.js +0 -0
  385. /package/{esm → dist}/react/context.js +0 -0
  386. /package/{esm → dist}/react/provider.js +0 -0
  387. /package/{esm → dist}/react/require-auth.d.ts +0 -0
  388. /package/{esm → dist}/react/use-authorization.js +0 -0
  389. /package/{esm → dist}/server/_clock-skew.d.ts +0 -0
  390. /package/{esm → dist}/server/client-authentication.js +0 -0
  391. /package/{esm → dist}/server/grants/client-credentials.js +0 -0
  392. /package/{esm → dist}/server/grants/password.js +0 -0
  393. /package/{esm → dist}/server/redirect-uri.d.ts +0 -0
  394. /package/{esm → dist}/server/services/authorization-code.js +0 -0
  395. /package/{esm → dist}/server/services/client.js +0 -0
  396. /package/{esm → dist}/server/services/device-authorization.js +0 -0
  397. /package/{esm → dist}/server/services/user.js +0 -0
  398. /package/{esm → dist}/server/utils/hash.d.ts +0 -0
  399. /package/{esm → dist}/testing/contract/_race.d.ts +0 -0
  400. /package/{esm → dist}/testing/contract/_race.js +0 -0
  401. /package/{esm → dist}/testing/contract/tenant.d.ts +0 -0
  402. /package/{esm → dist}/utils/_body.d.ts +0 -0
  403. /package/{esm → dist}/utils/_body.js +0 -0
  404. /package/{esm → dist}/utils/_buffer.d.ts +0 -0
  405. /package/{esm → dist}/utils/_buffer.js +0 -0
  406. /package/{esm → dist}/utils/_default-fetch.d.ts +0 -0
  407. /package/{esm → dist}/utils/_timing-safe.d.ts +0 -0
  408. /package/{esm → dist}/utils/_timing-safe.js +0 -0
  409. /package/{esm → dist}/utils/authentication-context.js +0 -0
  410. /package/{esm → dist}/utils/basic-auth.d.ts +0 -0
  411. /package/{esm → dist}/utils/basic-auth.js +0 -0
  412. /package/{esm → dist}/utils/pkce.d.ts +0 -0
  413. /package/{esm → dist}/utils/text.d.ts +0 -0
@@ -14,10 +14,8 @@
14
14
  *
15
15
  * @module
16
16
  */
17
- import "../../../_dnt.polyfills.js";
18
- import { assert, assertEquals, assertStrictEquals } from "../../../deps/jsr.io/@std/assert/1.0.19/mod.js";
19
- import { delay } from "../../../deps/jsr.io/@std/async/1.5.0/delay.js";
20
- import { beforeEach, describe, it } from "../../../deps/jsr.io/@std/testing/1.0.20/bdd.js";
17
+ import { assert, beforeEach, describe, expect, it } from "vitest";
18
+ import { delay } from "../../../utils/_delay.js";
21
19
  import { sessionStoreMaxAgeMs, } from "./session-store.js";
22
20
  /**
23
21
  * Seeds a session in `bff.sessionStore` and returns a `Cookie` header
@@ -53,8 +51,7 @@ export async function createTestSession(bff, options = {}) {
53
51
  const data = {
54
52
  tokens: {
55
53
  accessToken: options.tokens?.accessToken ?? crypto.randomUUID(),
56
- accessTokenExpiresAt: options.tokens?.accessTokenExpiresAt ??
57
- now + 60 * 60 * 1000,
54
+ accessTokenExpiresAt: options.tokens?.accessTokenExpiresAt ?? now + 60 * 60 * 1000,
58
55
  tokenType: options.tokens?.tokenType ?? "Bearer",
59
56
  scope: options.tokens?.scope,
60
57
  idToken: options.tokens?.idToken,
@@ -170,7 +167,7 @@ function parseCookieHeader(header, name) {
170
167
  const BOUND_MS = 1000;
171
168
  /**
172
169
  * Contract test suite for {@link SessionStore} implementations. Registers
173
- * `describe`/`it` blocks from `@std/testing/bdd`, so call it at a test
170
+ * `describe`/`it` blocks from Vitest, so call it at a test
174
171
  * module's top level. It does not check that a stateful store's `update`
175
172
  * rejects a missing or destroyed session, which {@link SessionStore.update}
176
173
  * requires — test that yourself.
@@ -199,28 +196,28 @@ export function runSessionStoreContractTests(options) {
199
196
  }
200
197
  it("create returns a non-empty cookie value", async () => {
201
198
  const value = await store.create(sampleSession());
202
- assertEquals(typeof value, "string");
199
+ expect(typeof value).toStrictEqual("string");
203
200
  assert(value.length > 0);
204
201
  });
205
202
  it("read returns null for an unknown cookie value", async () => {
206
- assertStrictEquals(await store.read("no-such-session"), null);
203
+ expect(await store.read("no-such-session")).toBe(null);
207
204
  });
208
205
  it("create + read round-trips the session data", async () => {
209
206
  const original = sampleSession();
210
207
  const value = await store.create(original);
211
208
  const fetched = await store.read(value);
212
209
  assert(fetched !== null, "read should return data for a created session");
213
- assertEquals(fetched.tokens.accessToken, original.tokens.accessToken);
214
- assertEquals(fetched.refreshToken, original.refreshToken);
215
- assertEquals(fetched.user, original.user);
210
+ expect(fetched.tokens.accessToken).toStrictEqual(original.tokens.accessToken);
211
+ expect(fetched.refreshToken).toStrictEqual(original.refreshToken);
212
+ expect(fetched.user).toStrictEqual(original.user);
216
213
  });
217
214
  it("preserves createdAt, which carries the session's absolute age", async () => {
218
215
  const original = sampleSession();
219
216
  const value = await store.create(original);
220
217
  const fetched = await store.read(value);
221
218
  assert(fetched !== null, "read should return data for a created session");
222
- assertEquals(fetched.createdAt, original.createdAt, "a store that drops createdAt silently opts its sessions out of " +
223
- "HonoBffOptions.sessionMaxAgeMs, so they never age out");
219
+ expect(fetched.createdAt, "a store that drops createdAt silently opts its sessions out of " +
220
+ "HonoBffOptions.sessionMaxAgeMs, so they never age out").toStrictEqual(original.createdAt);
224
221
  });
225
222
  it("update reflects changes on subsequent read", async () => {
226
223
  const value = await store.create(sampleSession());
@@ -231,34 +228,34 @@ export function runSessionStoreContractTests(options) {
231
228
  };
232
229
  const newValue = await store.update(value, updated);
233
230
  const fetched = await store.read(newValue);
234
- assertEquals(fetched?.user, { sub: "u1", role: "admin" });
231
+ expect(fetched?.user).toStrictEqual({ sub: "u1", role: "admin" });
235
232
  });
236
233
  if (destroyClearsRead) {
237
234
  it("destroy removes the session", async () => {
238
235
  const value = await store.create(sampleSession());
239
236
  await store.destroy(value);
240
- assertStrictEquals(await store.read(value), null);
237
+ expect(await store.read(value)).toBe(null);
241
238
  });
242
239
  }
243
240
  it("never advertises a max age without proving it enforces one", () => {
244
241
  const advertised = sessionStoreMaxAgeMs(store);
245
- assertEquals(advertised !== undefined && makeBoundedStore === undefined, false, `this store advertises maxAgeMs=${advertised}, which HonoBff trusts ` +
242
+ expect(advertised !== undefined && makeBoundedStore === undefined, `this store advertises maxAgeMs=${advertised}, which HonoBff trusts ` +
246
243
  "when it refuses a session cookie that would expire before the " +
247
244
  "session does. Supply makeBoundedStore so the contract can prove " +
248
- "the bound is real.");
245
+ "the bound is real.").toStrictEqual(false);
249
246
  });
250
247
  if (makeBoundedStore) {
251
248
  it("reports the max age it was built with, so a BFF can outlive it", async () => {
252
249
  const bounded = await makeBoundedStore(BOUND_MS);
253
- assertStrictEquals(sessionStoreMaxAgeMs(bounded), BOUND_MS, "a store that hides its bound gets no divergence check from HonoBff");
250
+ expect(sessionStoreMaxAgeMs(bounded), "a store that hides its bound gets no divergence check from HonoBff").toBe(BOUND_MS);
254
251
  });
255
252
  it("stops reading a session older than the max age it enforces", async () => {
256
253
  const bounded = await makeBoundedStore(BOUND_MS);
257
254
  const value = await bounded.create(sampleSession());
258
- assert(await bounded.read(value) !== null, "a session created moments ago must still read");
255
+ assert((await bounded.read(value)) !== null, "a session created moments ago must still read");
259
256
  await delay(BOUND_MS + 500);
260
- assertStrictEquals(await bounded.read(value), null, "a session past the store's own bound must stop reading, or a " +
261
- "captured cookie outlives the window the bound promises");
257
+ expect(await bounded.read(value), "a session past the store's own bound must stop reading, or a " +
258
+ "captured cookie outlives the window the bound promises").toBe(null);
262
259
  });
263
260
  }
264
261
  });
@@ -39,10 +39,9 @@
39
39
  *
40
40
  * @module
41
41
  */
42
- import "../../_dnt.polyfills.js";
43
42
  import { Hono } from "hono";
44
43
  import type { Context } from "hono";
45
- import type { IdentityService, IdentityUser } from "../../identity/service.js";
44
+ import type { IdentityService, IdentityUser } from "../../identity/service.ts";
46
45
  /** Paths for the routes mounted by {@link honoIdentityRoutes}. */
47
46
  export interface HonoIdentityPaths {
48
47
  /** `POST` sign-up. Default `/signup`. */
@@ -39,7 +39,6 @@
39
39
  *
40
40
  * @module
41
41
  */
42
- import "../../_dnt.polyfills.js";
43
42
  import { Hono } from "hono";
44
43
  import { identityErrorStatus, isIdentityError, } from "../../identity/errors.js";
45
44
  function handle(fn) {
@@ -68,10 +67,10 @@ async function readBody(c) {
68
67
  }
69
68
  const out = {};
70
69
  for (const [key, value] of Object.entries(body)) {
71
- out[key] = STRING_FIELDS.has(key) && value !== null &&
72
- value !== undefined
73
- ? String(value)
74
- : value;
70
+ out[key] =
71
+ STRING_FIELDS.has(key) && value !== null && value !== undefined
72
+ ? String(value)
73
+ : value;
75
74
  }
76
75
  return out;
77
76
  }
@@ -104,18 +103,19 @@ function isTrustedOrigin(c, allowedOrigins) {
104
103
  const origin = c.req.header("origin");
105
104
  const site = c.req.header("sec-fetch-site");
106
105
  if (site) {
107
- return site === "same-origin" || site === "none" ||
108
- (!!origin && allowedOrigins.has(origin));
106
+ return (site === "same-origin" ||
107
+ site === "none" ||
108
+ (!!origin && allowedOrigins.has(origin)));
109
109
  }
110
110
  if (!origin)
111
111
  return true;
112
- return allowedOrigins.has(origin) ||
113
- hostOf(origin) === new URL(c.req.url).host;
112
+ return (allowedOrigins.has(origin) || hostOf(origin) === new URL(c.req.url).host);
114
113
  }
115
114
  function sameOriginGuard(options) {
116
115
  const allowedOrigins = new Set(options.allowedOrigins ?? []);
117
116
  return async (c, next) => {
118
- if (!SAFE_METHODS.has(c.req.method) && !isTrustedOrigin(c, allowedOrigins)) {
117
+ if (!SAFE_METHODS.has(c.req.method) &&
118
+ !isTrustedOrigin(c, allowedOrigins)) {
119
119
  return c.json({ error: FORBIDDEN_ORIGIN }, identityErrorStatus(FORBIDDEN_ORIGIN));
120
120
  }
121
121
  await next();
@@ -3,7 +3,6 @@
3
3
  *
4
4
  * @module hono/log
5
5
  */
6
- import "../../_dnt.polyfills.js";
7
6
  import type { MiddlewareHandler } from "hono";
8
7
  /**
9
8
  * Produces a request target with every query value replaced by `[redacted]`.
@@ -1,9 +1,3 @@
1
- /**
2
- * Request logging that removes query values, including OAuth callback credentials.
3
- *
4
- * @module hono/log
5
- */
6
- import "../../_dnt.polyfills.js";
7
1
  /**
8
2
  * Produces a request target with every query value replaced by `[redacted]`.
9
3
  * Keeps the pathname and percent-encoded parameter names, including repeats,
@@ -27,13 +27,12 @@
27
27
  *
28
28
  * @module
29
29
  */
30
- import "../../_dnt.polyfills.js";
31
30
  import type { Context, MiddlewareHandler } from "hono";
32
- import type { ClientInterface } from "../../models/client.js";
33
- import type { AbstractScope, BasicScope } from "../../models/scope.js";
34
- import { type AuthenticatedContext, ResourceServer } from "../../server/resource-server.js";
35
- import type { RequireConditions } from "../../models/authorization.js";
36
- export { type HonoResourceServerVariables, OAUTH2_CONTEXT_KEY, } from "./_common.js";
31
+ import type { ClientInterface } from "../../models/client.ts";
32
+ import type { AbstractScope, BasicScope } from "../../models/scope.ts";
33
+ import { type AuthenticatedContext, ResourceServer } from "../../server/resource-server.ts";
34
+ import type { RequireConditions } from "../../models/authorization.ts";
35
+ export { type HonoResourceServerVariables, OAUTH2_CONTEXT_KEY, } from "./_common.ts";
37
36
  /**
38
37
  * Hono-specific wrapper around {@link ResourceServer}. Construction options
39
38
  * are identical to the core server; the subclass only adds Hono middleware
@@ -27,7 +27,6 @@
27
27
  *
28
28
  * @module
29
29
  */
30
- import "../../_dnt.polyfills.js";
31
30
  import { ResourceServer, } from "../../server/resource-server.js";
32
31
  import { authenticateHonoRequest, createProtectMiddleware, createRequireMiddleware, createRequireScopeMiddleware, readContext, } from "./_common.js";
33
32
  export { OAUTH2_CONTEXT_KEY, } from "./_common.js";
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from "./mod.js";
3
+ process.exitCode = await runCli(process.argv.slice(2));
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Configuration for the development identity provider: the shape of the JSON
3
+ * file `idp dev` reads, the built-in demo defaults, and the validation that
4
+ * turns untrusted JSON into a {@link DevIdpConfig}.
5
+ *
6
+ * @module
7
+ */
8
+ /** Grant types the development identity provider will serve. */
9
+ export interface DevIdpGrantsConfig {
10
+ /** Authorization code grant with PKCE. */
11
+ authorization_code: boolean;
12
+ /** Client credentials grant (machine-to-machine). */
13
+ client_credentials: boolean;
14
+ /** Refresh token grant. */
15
+ refresh_token: boolean;
16
+ /** Resource owner password credentials grant. */
17
+ password: boolean;
18
+ }
19
+ /** A user seeded into the development identity provider at startup. */
20
+ export interface DevIdpUserConfig {
21
+ /** Subject identifier: the `sub` claim and the id the admin API takes. */
22
+ id: string;
23
+ /** Login name typed into the sign-in form. */
24
+ username: string;
25
+ /** Password the sign-in form accepts. Plaintext, because this is a dev tool. */
26
+ password: string;
27
+ /** Extra claims merged into this user's id_token and UserInfo response. */
28
+ claims: Record<string, unknown>;
29
+ }
30
+ /** A client registered with the development identity provider at startup. */
31
+ export interface DevIdpClientConfig {
32
+ /** The `client_id` the application authenticates with. */
33
+ id: string;
34
+ /** Omit for a public (PKCE-only) client; set for a confidential one. */
35
+ secret?: string;
36
+ /**
37
+ * Redirect URIs, matched exactly — list every one your app sends. An entry
38
+ * on `127.0.0.1` or `[::1]` also matches the same URI on any port.
39
+ */
40
+ redirectUris: string[];
41
+ /** Grant types this client may use. */
42
+ grants: string[];
43
+ /**
44
+ * User the client-credentials grant puts on the token. Omit it — the
45
+ * default — for a machine token with no user, which introspection reports
46
+ * with a `client_id` and no `sub`. Set it only to model a dedicated
47
+ * service-account user, never a human owner.
48
+ */
49
+ ownerUserId?: string;
50
+ }
51
+ /**
52
+ * A fully resolved configuration. Every field the server needs is present:
53
+ * {@link parseDevIdpConfig} fills the defaults so nothing downstream has to.
54
+ */
55
+ export interface DevIdpConfig {
56
+ /**
57
+ * Issuer identifier stamped into tokens and discovery. When omitted it is
58
+ * pinned at startup to the bound address (`localhost` for a wildcard bind
59
+ * such as `0.0.0.0`); set it when clients reach the server under another
60
+ * name, such as a CI service hostname.
61
+ */
62
+ issuer?: string;
63
+ /** Interface to bind. */
64
+ hostname: string;
65
+ /** Port to bind. `0` asks the OS for a free one. */
66
+ port: number;
67
+ /** `"prompt"` shows a consent screen; `"auto"` grants the requested scope. */
68
+ consent: "auto" | "prompt";
69
+ /** Scope vocabulary advertised in discovery. */
70
+ scopesSupported: string[];
71
+ /** Access token lifetime in seconds — shorten it to test expiry handling. */
72
+ accessTokenLifetime: number;
73
+ /** Grant types the server enables. */
74
+ grants: DevIdpGrantsConfig;
75
+ /**
76
+ * ES256 private JWK, as printed by `oidc keygen`. Pins the signing key so
77
+ * tokens and JWKS survive a restart. `OIDC_SIGNING_KEY` overrides it.
78
+ */
79
+ signingKey?: JsonWebKey & {
80
+ kid?: string;
81
+ };
82
+ /** Users to seed. */
83
+ users: DevIdpUserConfig[];
84
+ /** Clients to register. */
85
+ clients: DevIdpClientConfig[];
86
+ }
87
+ /**
88
+ * The configuration used when `idp dev` runs without `--config`: one
89
+ * confidential client, one public client, and one user, all on well-known
90
+ * localhost ports.
91
+ */
92
+ export declare function defaultDevIdpConfig(): DevIdpConfig;
93
+ /**
94
+ * Validates parsed JSON and fills in defaults, so the caller gets a config
95
+ * with no optional plumbing left to resolve.
96
+ *
97
+ * Unknown fields are rejected rather than ignored — a typo in a dev config is
98
+ * otherwise a silent no-op that costs an hour.
99
+ *
100
+ * @throws {Error} When a field is missing, mistyped, or unrecognized. The
101
+ * message names the offending path (e.g. `users[0].password`).
102
+ */
103
+ export declare function parseDevIdpConfig(value: unknown): DevIdpConfig;
104
+ /**
105
+ * Reads and validates a config file.
106
+ *
107
+ * @throws {Error} When the file is unreadable, is not valid JSON, or fails
108
+ * {@link parseDevIdpConfig}. Every message names the file.
109
+ */
110
+ export declare function loadDevIdpConfig(path: string): Promise<DevIdpConfig>;
@@ -0,0 +1,269 @@
1
+ /**
2
+ * Configuration for the development identity provider: the shape of the JSON
3
+ * file `idp dev` reads, the built-in demo defaults, and the validation that
4
+ * turns untrusted JSON into a {@link DevIdpConfig}.
5
+ *
6
+ * @module
7
+ */
8
+ import { readFile } from "node:fs/promises";
9
+ const DEFAULT_PORT = 9000;
10
+ const DEFAULT_HOSTNAME = "127.0.0.1";
11
+ const DEFAULT_ACCESS_TOKEN_LIFETIME = 3600;
12
+ const DEFAULT_SCOPES = ["openid", "profile", "email", "offline_access"];
13
+ const DEFAULT_GRANTS = {
14
+ authorization_code: true,
15
+ client_credentials: true,
16
+ refresh_token: true,
17
+ password: false,
18
+ };
19
+ const DEFAULT_REDIRECT_URIS = [
20
+ "http://localhost:3000/callback",
21
+ "http://localhost:5173/callback",
22
+ "http://localhost:8000/callback",
23
+ ];
24
+ const DEFAULT_CLIENT_GRANTS = ["authorization_code", "refresh_token"];
25
+ const CONFIG_FIELDS = [
26
+ "issuer",
27
+ "hostname",
28
+ "port",
29
+ "consent",
30
+ "scopesSupported",
31
+ "accessTokenLifetime",
32
+ "grants",
33
+ "signingKey",
34
+ "users",
35
+ "clients",
36
+ ];
37
+ const USER_FIELDS = ["id", "username", "password", "claims"];
38
+ const CLIENT_FIELDS = ["id", "secret", "redirectUris", "grants", "ownerUserId"];
39
+ /**
40
+ * The configuration used when `idp dev` runs without `--config`: one
41
+ * confidential client, one public client, and one user, all on well-known
42
+ * localhost ports.
43
+ */
44
+ export function defaultDevIdpConfig() {
45
+ return {
46
+ hostname: DEFAULT_HOSTNAME,
47
+ port: DEFAULT_PORT,
48
+ consent: "auto",
49
+ scopesSupported: [...DEFAULT_SCOPES],
50
+ accessTokenLifetime: DEFAULT_ACCESS_TOKEN_LIFETIME,
51
+ grants: { ...DEFAULT_GRANTS },
52
+ users: [
53
+ {
54
+ id: "user-alice",
55
+ username: "alice@example.com",
56
+ password: "password",
57
+ claims: {
58
+ name: "Alice Example",
59
+ email: "alice@example.com",
60
+ email_verified: true,
61
+ },
62
+ },
63
+ ],
64
+ clients: [
65
+ {
66
+ id: "dev-client",
67
+ secret: "dev-secret",
68
+ redirectUris: [...DEFAULT_REDIRECT_URIS],
69
+ grants: ["authorization_code", "refresh_token", "client_credentials"],
70
+ ownerUserId: "user-alice",
71
+ },
72
+ {
73
+ id: "dev-public-client",
74
+ redirectUris: [...DEFAULT_REDIRECT_URIS],
75
+ grants: [...DEFAULT_CLIENT_GRANTS],
76
+ },
77
+ ],
78
+ };
79
+ }
80
+ function fail(path, expectation) {
81
+ throw new Error(`${path} ${expectation}`);
82
+ }
83
+ function record(value, path) {
84
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
85
+ fail(path, "must be an object");
86
+ }
87
+ return value;
88
+ }
89
+ function rejectUnknown(value, path, allowed) {
90
+ for (const key of Object.keys(value)) {
91
+ if (!allowed.includes(key)) {
92
+ fail(`${path}.${key}`, `is not a known option (expected one of: ${allowed.join(", ")})`);
93
+ }
94
+ }
95
+ }
96
+ function string(value, path) {
97
+ if (typeof value !== "string" || value.length === 0) {
98
+ fail(path, "must be a non-empty string");
99
+ }
100
+ return value;
101
+ }
102
+ function optionalString(value, path) {
103
+ return value === undefined ? undefined : string(value, path);
104
+ }
105
+ function stringArray(value, path) {
106
+ if (!Array.isArray(value))
107
+ fail(path, "must be an array of strings");
108
+ return value.map((entry, index) => string(entry, `${path}[${index}]`));
109
+ }
110
+ function integer(value, path, min) {
111
+ if (typeof value !== "number" || !Number.isInteger(value) || value < min) {
112
+ fail(path, `must be an integer >= ${min}`);
113
+ }
114
+ return value;
115
+ }
116
+ function boolean(value, path) {
117
+ if (typeof value !== "boolean")
118
+ fail(path, "must be true or false");
119
+ return value;
120
+ }
121
+ function array(value, path) {
122
+ if (!Array.isArray(value))
123
+ fail(path, "must be an array");
124
+ return value;
125
+ }
126
+ function parseGrants(value, path) {
127
+ const source = record(value, path);
128
+ rejectUnknown(source, path, Object.keys(DEFAULT_GRANTS));
129
+ const grants = { ...DEFAULT_GRANTS };
130
+ for (const key of Object.keys(DEFAULT_GRANTS)) {
131
+ if (source[key] !== undefined) {
132
+ grants[key] = boolean(source[key], `${path}.${key}`);
133
+ }
134
+ }
135
+ return grants;
136
+ }
137
+ function parseUser(value, path) {
138
+ const source = record(value, path);
139
+ rejectUnknown(source, path, USER_FIELDS);
140
+ const username = string(source.username, `${path}.username`);
141
+ return {
142
+ id: optionalString(source.id, `${path}.id`) ?? username,
143
+ username,
144
+ password: string(source.password, `${path}.password`),
145
+ claims: source.claims === undefined
146
+ ? {}
147
+ : record(source.claims, `${path}.claims`),
148
+ };
149
+ }
150
+ function parseClient(value, path) {
151
+ const source = record(value, path);
152
+ rejectUnknown(source, path, CLIENT_FIELDS);
153
+ const grants = source.grants === undefined
154
+ ? [...DEFAULT_CLIENT_GRANTS]
155
+ : stringArray(source.grants, `${path}.grants`);
156
+ const redirectUris = source.redirectUris === undefined
157
+ ? []
158
+ : stringArray(source.redirectUris, `${path}.redirectUris`);
159
+ if (grants.includes("authorization_code") && redirectUris.length === 0) {
160
+ fail(`${path}.redirectUris`, "must list at least one URI for a client using the authorization_code grant");
161
+ }
162
+ return {
163
+ id: string(source.id, `${path}.id`),
164
+ secret: optionalString(source.secret, `${path}.secret`),
165
+ redirectUris,
166
+ grants,
167
+ ownerUserId: optionalString(source.ownerUserId, `${path}.ownerUserId`),
168
+ };
169
+ }
170
+ function parseConsent(value, path) {
171
+ const consent = string(value, path);
172
+ if (consent !== "auto" && consent !== "prompt") {
173
+ fail(path, 'must be "auto" or "prompt"');
174
+ }
175
+ return consent;
176
+ }
177
+ function parseSigningKey(value, path) {
178
+ const jwk = record(value, path);
179
+ string(jwk.kty, `${path}.kty`);
180
+ string(jwk.d, `${path}.d`);
181
+ return jwk;
182
+ }
183
+ /**
184
+ * Validates parsed JSON and fills in defaults, so the caller gets a config
185
+ * with no optional plumbing left to resolve.
186
+ *
187
+ * Unknown fields are rejected rather than ignored — a typo in a dev config is
188
+ * otherwise a silent no-op that costs an hour.
189
+ *
190
+ * @throws {Error} When a field is missing, mistyped, or unrecognized. The
191
+ * message names the offending path (e.g. `users[0].password`).
192
+ */
193
+ export function parseDevIdpConfig(value) {
194
+ const source = record(value, "config");
195
+ rejectUnknown(source, "config", CONFIG_FIELDS);
196
+ const defaults = defaultDevIdpConfig();
197
+ const users = source.users === undefined
198
+ ? defaults.users
199
+ : array(source.users, "config.users").map((entry, index) => parseUser(entry, `users[${index}]`));
200
+ const clients = source.clients === undefined
201
+ ? defaults.clients
202
+ : array(source.clients, "config.clients").map((entry, index) => parseClient(entry, `clients[${index}]`));
203
+ const seenUserIds = new Set();
204
+ for (const user of users) {
205
+ if (seenUserIds.has(user.id)) {
206
+ fail(`users`, `contains more than one user with id "${user.id}"`);
207
+ }
208
+ seenUserIds.add(user.id);
209
+ }
210
+ const seenClientIds = new Set();
211
+ for (const client of clients) {
212
+ if (seenClientIds.has(client.id)) {
213
+ fail(`clients`, `contains more than one client with id "${client.id}"`);
214
+ }
215
+ seenClientIds.add(client.id);
216
+ }
217
+ return {
218
+ issuer: optionalString(source.issuer, "config.issuer"),
219
+ hostname: optionalString(source.hostname, "config.hostname") ?? defaults.hostname,
220
+ port: source.port === undefined
221
+ ? defaults.port
222
+ : integer(source.port, "config.port", 0),
223
+ consent: source.consent === undefined
224
+ ? defaults.consent
225
+ : parseConsent(source.consent, "config.consent"),
226
+ scopesSupported: source.scopesSupported === undefined
227
+ ? defaults.scopesSupported
228
+ : stringArray(source.scopesSupported, "config.scopesSupported"),
229
+ accessTokenLifetime: source.accessTokenLifetime === undefined
230
+ ? defaults.accessTokenLifetime
231
+ : integer(source.accessTokenLifetime, "config.accessTokenLifetime", 1),
232
+ grants: source.grants === undefined
233
+ ? defaults.grants
234
+ : parseGrants(source.grants, "config.grants"),
235
+ signingKey: source.signingKey === undefined
236
+ ? undefined
237
+ : parseSigningKey(source.signingKey, "config.signingKey"),
238
+ users,
239
+ clients,
240
+ };
241
+ }
242
+ /**
243
+ * Reads and validates a config file.
244
+ *
245
+ * @throws {Error} When the file is unreadable, is not valid JSON, or fails
246
+ * {@link parseDevIdpConfig}. Every message names the file.
247
+ */
248
+ export async function loadDevIdpConfig(path) {
249
+ let text;
250
+ try {
251
+ text = await readFile(path, "utf8");
252
+ }
253
+ catch (error) {
254
+ throw new Error(`cannot read config ${path}: ${error instanceof Error ? error.message : String(error)}`);
255
+ }
256
+ let parsed;
257
+ try {
258
+ parsed = JSON.parse(text);
259
+ }
260
+ catch (error) {
261
+ throw new Error(`${path} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
262
+ }
263
+ try {
264
+ return parseDevIdpConfig(parsed);
265
+ }
266
+ catch (error) {
267
+ throw new Error(`${path}: ${error instanceof Error ? error.message : String(error)}`);
268
+ }
269
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The `idp dev` command: runs the development identity provider from a config
3
+ * file (or the built-in demo config) and prints what it seeded.
4
+ *
5
+ * @module
6
+ */
7
+ /**
8
+ * Runs the development identity provider until the process is stopped.
9
+ *
10
+ * Accepts `--config <path>`, `--port <number>`, `--hostname <host>`,
11
+ * `--issuer <url>`, `--admin-token <token>`, and `--unsafe-remote-access`;
12
+ * flags win over the config file, which wins over the built-in demo config.
13
+ * `IDP_ADMIN_TOKEN` supplies the admin token when the flag is absent.
14
+ *
15
+ * Aborting `signal` shuts the server down and resolves the returned promise.
16
+ *
17
+ * @throws {Error} When an option or the config file is invalid, or when the
18
+ * bind address is not loopback and `--unsafe-remote-access` was not passed.
19
+ */
20
+ export declare function idpDev(args: string[], signal?: AbortSignal): Promise<void>;