@_mustachio/openauth 0.9.1 → 0.10.0

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 (712) hide show
  1. package/dist/esm/adapters/d1/audit-log.js +15 -0
  2. package/dist/esm/adapters/d1/config-store.js +45 -0
  3. package/dist/esm/adapters/d1/index.js +12 -0
  4. package/dist/esm/adapters/d1/key-store.js +116 -0
  5. package/dist/esm/adapters/d1/method-store.js +52 -0
  6. package/dist/esm/adapters/d1/migrations.js +77 -0
  7. package/dist/esm/adapters/d1/session-store.js +134 -0
  8. package/dist/esm/adapters/d1/session.js +18 -0
  9. package/dist/esm/adapters/d1/token-store.js +140 -0
  10. package/dist/esm/adapters/durable-object/index.js +3 -0
  11. package/dist/esm/adapters/durable-object/session-store.js +139 -0
  12. package/dist/esm/adapters/durable-object/types.js +0 -0
  13. package/dist/esm/adapters/dynamo/audit-log.js +23 -0
  14. package/dist/esm/adapters/dynamo/client.js +0 -0
  15. package/dist/esm/adapters/dynamo/config-store.js +57 -0
  16. package/dist/esm/adapters/dynamo/index.js +10 -0
  17. package/dist/esm/adapters/dynamo/key-store.js +188 -0
  18. package/dist/esm/adapters/dynamo/method-store.js +72 -0
  19. package/dist/esm/adapters/dynamo/passkey-credential-store.js +83 -0
  20. package/dist/esm/adapters/dynamo/sdk.js +128 -0
  21. package/dist/esm/adapters/dynamo/session-store.js +173 -0
  22. package/dist/esm/adapters/dynamo/token-store.js +178 -0
  23. package/dist/esm/adapters/kms/in-memory-backing.js +28 -0
  24. package/dist/esm/adapters/kms/index.js +5 -0
  25. package/dist/esm/adapters/kms/key-store.js +129 -0
  26. package/dist/esm/adapters/kms/sdk.js +23 -0
  27. package/dist/esm/adapters/kms/types.js +0 -0
  28. package/dist/esm/adapters/kv/audit-log.js +21 -0
  29. package/dist/esm/adapters/kv/config-store.js +43 -0
  30. package/dist/esm/adapters/kv/index.js +5 -0
  31. package/dist/esm/adapters/kv/method-store.js +63 -0
  32. package/dist/esm/adapters/kv/types.js +0 -0
  33. package/dist/esm/adapters/memory/audit-log.js +16 -0
  34. package/dist/esm/adapters/memory/clock.js +5 -0
  35. package/dist/esm/adapters/memory/config-store.js +31 -0
  36. package/dist/esm/adapters/memory/index.js +10 -0
  37. package/dist/esm/adapters/memory/key-store.js +78 -0
  38. package/dist/esm/adapters/memory/method-store.js +43 -0
  39. package/dist/esm/adapters/memory/passkey-credential-store.js +53 -0
  40. package/dist/esm/adapters/memory/session-store.js +82 -0
  41. package/dist/esm/adapters/memory/token-store.js +91 -0
  42. package/dist/esm/adapters/postgres/audit-log.js +16 -0
  43. package/dist/esm/adapters/postgres/config-store.js +48 -0
  44. package/dist/esm/adapters/postgres/executor.js +21 -0
  45. package/dist/esm/adapters/postgres/index.js +13 -0
  46. package/dist/esm/adapters/postgres/key-store.js +191 -0
  47. package/dist/esm/adapters/postgres/method-store.js +61 -0
  48. package/dist/esm/adapters/postgres/migrations.js +111 -0
  49. package/dist/esm/adapters/postgres/passkey-credential-store.js +80 -0
  50. package/dist/esm/adapters/postgres/session-store.js +135 -0
  51. package/dist/esm/adapters/postgres/token-store.js +151 -0
  52. package/dist/esm/client.js +26 -10
  53. package/dist/esm/domain/audit.js +13 -0
  54. package/dist/esm/domain/authorize.js +212 -0
  55. package/dist/esm/domain/callback.js +173 -0
  56. package/dist/esm/domain/client-auth.js +61 -0
  57. package/dist/esm/domain/client-credentials.js +91 -0
  58. package/dist/esm/domain/crypto.js +97 -0
  59. package/dist/esm/domain/discovery.js +41 -0
  60. package/dist/esm/domain/introspect.js +51 -0
  61. package/dist/esm/domain/jwt.js +43 -0
  62. package/dist/esm/domain/method-cache.js +136 -0
  63. package/dist/esm/domain/method-dispatch.js +36 -0
  64. package/dist/esm/domain/method-route.js +108 -0
  65. package/dist/esm/domain/pkce.js +16 -0
  66. package/dist/esm/domain/refresh.js +91 -0
  67. package/dist/esm/domain/revoke.js +81 -0
  68. package/dist/esm/domain/state-envelope.js +80 -0
  69. package/dist/esm/domain/token-exchange.js +101 -0
  70. package/dist/esm/domain/token.js +205 -0
  71. package/dist/esm/domain/userinfo.js +27 -0
  72. package/dist/esm/http/context.js +7 -0
  73. package/dist/esm/http/cookies.js +98 -0
  74. package/dist/esm/http/errors.js +71 -0
  75. package/dist/esm/http/handlers/authorize.js +163 -0
  76. package/dist/esm/http/handlers/callback.js +53 -0
  77. package/dist/esm/http/handlers/metadata.js +34 -0
  78. package/dist/esm/http/handlers/method-route.js +87 -0
  79. package/dist/esm/http/handlers/revocation.js +98 -0
  80. package/dist/esm/http/handlers/token.js +167 -0
  81. package/dist/esm/http/handlers/userinfo.js +54 -0
  82. package/dist/esm/http/middleware/error.js +15 -0
  83. package/dist/esm/http/middleware/tenant.js +102 -0
  84. package/dist/esm/http/resolver.js +15 -0
  85. package/dist/esm/http/router.js +35 -0
  86. package/dist/esm/http/schemas/authorize.js +24 -0
  87. package/dist/esm/http/schemas/revocation.js +18 -0
  88. package/dist/esm/http/schemas/token.js +57 -0
  89. package/dist/esm/index.js +121 -9
  90. package/dist/esm/methods/code.js +221 -0
  91. package/dist/esm/methods/m2m.js +41 -0
  92. package/dist/esm/methods/oauth2-factory.js +84 -0
  93. package/dist/esm/methods/oauth2-generic.js +196 -0
  94. package/dist/esm/methods/oidc-generic.js +53 -0
  95. package/dist/esm/methods/passkey.js +275 -0
  96. package/dist/esm/methods/password-hash.js +79 -0
  97. package/dist/esm/methods/password.js +166 -0
  98. package/dist/esm/methods/providers/apple.js +29 -0
  99. package/dist/esm/methods/providers/cognito.js +37 -0
  100. package/dist/esm/methods/providers/discord.js +28 -0
  101. package/dist/esm/methods/providers/facebook.js +42 -0
  102. package/dist/esm/methods/providers/github.js +29 -0
  103. package/dist/esm/methods/providers/google.js +29 -0
  104. package/dist/esm/methods/providers/index.js +17 -0
  105. package/dist/esm/methods/providers/jumpcloud.js +27 -0
  106. package/dist/esm/methods/providers/keycloak.js +32 -0
  107. package/dist/esm/methods/providers/linkedin.js +28 -0
  108. package/dist/esm/methods/providers/microsoft.js +28 -0
  109. package/dist/esm/methods/providers/slack.js +30 -0
  110. package/dist/esm/methods/providers/spotify.js +28 -0
  111. package/dist/esm/methods/providers/twitch.js +28 -0
  112. package/dist/esm/methods/providers/x.js +28 -0
  113. package/dist/esm/methods/providers/yahoo.js +27 -0
  114. package/dist/esm/pkce.js +4 -16
  115. package/dist/esm/ports/audit-log.js +0 -0
  116. package/dist/esm/ports/config-store.js +0 -0
  117. package/dist/esm/ports/key-store.js +0 -0
  118. package/dist/esm/ports/method-store.js +0 -0
  119. package/dist/esm/ports/session-store.js +0 -0
  120. package/dist/esm/ports/token-store.js +0 -0
  121. package/dist/esm/types/authorization.js +0 -0
  122. package/dist/esm/types/error.js +65 -0
  123. package/dist/esm/types/flow.js +0 -0
  124. package/dist/esm/types/idp.js +0 -0
  125. package/dist/esm/types/method.js +0 -0
  126. package/dist/esm/types/picker.js +0 -0
  127. package/dist/esm/types/result.js +11 -0
  128. package/dist/esm/types/subject.js +0 -0
  129. package/dist/esm/types/tenant.js +5 -0
  130. package/dist/esm/types/token.js +0 -0
  131. package/dist/esm/ui/forms.js +253 -0
  132. package/dist/esm/ui/index.js +8 -0
  133. package/dist/esm/ui/picker.js +49 -0
  134. package/dist/types/adapters/d1/audit-log.d.ts +19 -0
  135. package/dist/types/adapters/d1/audit-log.d.ts.map +1 -0
  136. package/dist/types/adapters/d1/config-store.d.ts +20 -0
  137. package/dist/types/adapters/d1/config-store.d.ts.map +1 -0
  138. package/dist/types/adapters/d1/index.d.ts +35 -0
  139. package/dist/types/adapters/d1/index.d.ts.map +1 -0
  140. package/dist/types/adapters/d1/key-store.d.ts +17 -0
  141. package/dist/types/adapters/d1/key-store.d.ts.map +1 -0
  142. package/dist/types/adapters/d1/method-store.d.ts +21 -0
  143. package/dist/types/adapters/d1/method-store.d.ts.map +1 -0
  144. package/dist/types/adapters/d1/migrations.d.ts +18 -0
  145. package/dist/types/adapters/d1/migrations.d.ts.map +1 -0
  146. package/dist/types/adapters/d1/session-store.d.ts +20 -0
  147. package/dist/types/adapters/d1/session-store.d.ts.map +1 -0
  148. package/dist/types/adapters/d1/session.d.ts +18 -0
  149. package/dist/types/adapters/d1/session.d.ts.map +1 -0
  150. package/dist/types/adapters/d1/token-store.d.ts +29 -0
  151. package/dist/types/adapters/d1/token-store.d.ts.map +1 -0
  152. package/dist/types/adapters/d1/types.d.ts +43 -0
  153. package/dist/types/adapters/d1/types.d.ts.map +1 -0
  154. package/dist/types/adapters/durable-object/index.d.ts +17 -0
  155. package/dist/types/adapters/durable-object/index.d.ts.map +1 -0
  156. package/dist/types/adapters/durable-object/session-store.d.ts +21 -0
  157. package/dist/types/adapters/durable-object/session-store.d.ts.map +1 -0
  158. package/dist/types/adapters/durable-object/types.d.ts +23 -0
  159. package/dist/types/adapters/durable-object/types.d.ts.map +1 -0
  160. package/dist/types/adapters/dynamo/audit-log.d.ts +19 -0
  161. package/dist/types/adapters/dynamo/audit-log.d.ts.map +1 -0
  162. package/dist/types/adapters/dynamo/client.d.ts +111 -0
  163. package/dist/types/adapters/dynamo/client.d.ts.map +1 -0
  164. package/dist/types/adapters/dynamo/config-store.d.ts +21 -0
  165. package/dist/types/adapters/dynamo/config-store.d.ts.map +1 -0
  166. package/dist/types/adapters/dynamo/index.d.ts +60 -0
  167. package/dist/types/adapters/dynamo/index.d.ts.map +1 -0
  168. package/dist/types/adapters/dynamo/key-store.d.ts +23 -0
  169. package/dist/types/adapters/dynamo/key-store.d.ts.map +1 -0
  170. package/dist/types/adapters/dynamo/method-store.d.ts +20 -0
  171. package/dist/types/adapters/dynamo/method-store.d.ts.map +1 -0
  172. package/dist/types/adapters/dynamo/passkey-credential-store.d.ts +47 -0
  173. package/dist/types/adapters/dynamo/passkey-credential-store.d.ts.map +1 -0
  174. package/dist/types/adapters/dynamo/sdk.d.ts +23 -0
  175. package/dist/types/adapters/dynamo/sdk.d.ts.map +1 -0
  176. package/dist/types/adapters/dynamo/session-store.d.ts +20 -0
  177. package/dist/types/adapters/dynamo/session-store.d.ts.map +1 -0
  178. package/dist/types/adapters/dynamo/token-store.d.ts +29 -0
  179. package/dist/types/adapters/dynamo/token-store.d.ts.map +1 -0
  180. package/dist/types/adapters/kms/in-memory-backing.d.ts +9 -0
  181. package/dist/types/adapters/kms/in-memory-backing.d.ts.map +1 -0
  182. package/dist/types/adapters/kms/index.d.ts +35 -0
  183. package/dist/types/adapters/kms/index.d.ts.map +1 -0
  184. package/dist/types/adapters/kms/key-store.d.ts +20 -0
  185. package/dist/types/adapters/kms/key-store.d.ts.map +1 -0
  186. package/dist/types/adapters/kms/sdk.d.ts +16 -0
  187. package/dist/types/adapters/kms/sdk.d.ts.map +1 -0
  188. package/dist/types/adapters/kms/types.d.ts +58 -0
  189. package/dist/types/adapters/kms/types.d.ts.map +1 -0
  190. package/dist/types/adapters/kv/audit-log.d.ts +22 -0
  191. package/dist/types/adapters/kv/audit-log.d.ts.map +1 -0
  192. package/dist/types/adapters/kv/config-store.d.ts +25 -0
  193. package/dist/types/adapters/kv/config-store.d.ts.map +1 -0
  194. package/dist/types/adapters/kv/index.d.ts +21 -0
  195. package/dist/types/adapters/kv/index.d.ts.map +1 -0
  196. package/dist/types/adapters/kv/method-store.d.ts +23 -0
  197. package/dist/types/adapters/kv/method-store.d.ts.map +1 -0
  198. package/dist/types/adapters/kv/types.d.ts +28 -0
  199. package/dist/types/adapters/kv/types.d.ts.map +1 -0
  200. package/dist/types/adapters/memory/audit-log.d.ts +18 -0
  201. package/dist/types/adapters/memory/audit-log.d.ts.map +1 -0
  202. package/dist/types/adapters/memory/clock.d.ts +7 -0
  203. package/dist/types/adapters/memory/clock.d.ts.map +1 -0
  204. package/dist/types/adapters/memory/config-store.d.ts +19 -0
  205. package/dist/types/adapters/memory/config-store.d.ts.map +1 -0
  206. package/dist/types/adapters/memory/index.d.ts +15 -0
  207. package/dist/types/adapters/memory/index.d.ts.map +1 -0
  208. package/dist/types/adapters/memory/key-store.d.ts +17 -0
  209. package/dist/types/adapters/memory/key-store.d.ts.map +1 -0
  210. package/dist/types/adapters/memory/method-store.d.ts +26 -0
  211. package/dist/types/adapters/memory/method-store.d.ts.map +1 -0
  212. package/dist/types/adapters/memory/passkey-credential-store.d.ts +43 -0
  213. package/dist/types/adapters/memory/passkey-credential-store.d.ts.map +1 -0
  214. package/dist/types/adapters/memory/session-store.d.ts +19 -0
  215. package/dist/types/adapters/memory/session-store.d.ts.map +1 -0
  216. package/dist/types/adapters/memory/token-store.d.ts +28 -0
  217. package/dist/types/adapters/memory/token-store.d.ts.map +1 -0
  218. package/dist/types/adapters/postgres/audit-log.d.ts +18 -0
  219. package/dist/types/adapters/postgres/audit-log.d.ts.map +1 -0
  220. package/dist/types/adapters/postgres/config-store.d.ts +21 -0
  221. package/dist/types/adapters/postgres/config-store.d.ts.map +1 -0
  222. package/dist/types/adapters/postgres/executor.d.ts +48 -0
  223. package/dist/types/adapters/postgres/executor.d.ts.map +1 -0
  224. package/dist/types/adapters/postgres/index.d.ts +39 -0
  225. package/dist/types/adapters/postgres/index.d.ts.map +1 -0
  226. package/dist/types/adapters/postgres/key-store.d.ts +23 -0
  227. package/dist/types/adapters/postgres/key-store.d.ts.map +1 -0
  228. package/dist/types/adapters/postgres/method-store.d.ts +21 -0
  229. package/dist/types/adapters/postgres/method-store.d.ts.map +1 -0
  230. package/dist/types/adapters/postgres/migrations.d.ts +22 -0
  231. package/dist/types/adapters/postgres/migrations.d.ts.map +1 -0
  232. package/dist/types/adapters/postgres/passkey-credential-store.d.ts +48 -0
  233. package/dist/types/adapters/postgres/passkey-credential-store.d.ts.map +1 -0
  234. package/dist/types/adapters/postgres/session-store.d.ts +20 -0
  235. package/dist/types/adapters/postgres/session-store.d.ts.map +1 -0
  236. package/dist/types/adapters/postgres/token-store.d.ts +30 -0
  237. package/dist/types/adapters/postgres/token-store.d.ts.map +1 -0
  238. package/dist/types/client.d.ts +1 -1
  239. package/dist/types/client.d.ts.map +1 -1
  240. package/dist/types/domain/audit.d.ts +17 -0
  241. package/dist/types/domain/audit.d.ts.map +1 -0
  242. package/dist/types/domain/authorize.d.ts +125 -0
  243. package/dist/types/domain/authorize.d.ts.map +1 -0
  244. package/dist/types/domain/callback.d.ts +70 -0
  245. package/dist/types/domain/callback.d.ts.map +1 -0
  246. package/dist/types/domain/client-auth.d.ts +57 -0
  247. package/dist/types/domain/client-auth.d.ts.map +1 -0
  248. package/dist/types/domain/client-credentials.d.ts +52 -0
  249. package/dist/types/domain/client-credentials.d.ts.map +1 -0
  250. package/dist/types/domain/crypto.d.ts +53 -0
  251. package/dist/types/domain/crypto.d.ts.map +1 -0
  252. package/dist/types/domain/discovery.d.ts +44 -0
  253. package/dist/types/domain/discovery.d.ts.map +1 -0
  254. package/dist/types/domain/introspect.d.ts +71 -0
  255. package/dist/types/domain/introspect.d.ts.map +1 -0
  256. package/dist/types/domain/jwt.d.ts +48 -0
  257. package/dist/types/domain/jwt.d.ts.map +1 -0
  258. package/dist/types/domain/method-cache.d.ts +42 -0
  259. package/dist/types/domain/method-cache.d.ts.map +1 -0
  260. package/dist/types/domain/method-dispatch.d.ts +37 -0
  261. package/dist/types/domain/method-dispatch.d.ts.map +1 -0
  262. package/dist/types/domain/method-route.d.ts +77 -0
  263. package/dist/types/domain/method-route.d.ts.map +1 -0
  264. package/dist/types/domain/pkce.d.ts +15 -0
  265. package/dist/types/domain/pkce.d.ts.map +1 -0
  266. package/dist/types/domain/refresh.d.ts +43 -0
  267. package/dist/types/domain/refresh.d.ts.map +1 -0
  268. package/dist/types/domain/revoke.d.ts +61 -0
  269. package/dist/types/domain/revoke.d.ts.map +1 -0
  270. package/dist/types/domain/state-envelope.d.ts +30 -0
  271. package/dist/types/domain/state-envelope.d.ts.map +1 -0
  272. package/dist/types/domain/token-exchange.d.ts +67 -0
  273. package/dist/types/domain/token-exchange.d.ts.map +1 -0
  274. package/dist/types/domain/token.d.ts +100 -0
  275. package/dist/types/domain/token.d.ts.map +1 -0
  276. package/dist/types/domain/userinfo.d.ts +22 -0
  277. package/dist/types/domain/userinfo.d.ts.map +1 -0
  278. package/dist/types/http/context.d.ts +63 -0
  279. package/dist/types/http/context.d.ts.map +1 -0
  280. package/dist/types/http/cookies.d.ts +45 -0
  281. package/dist/types/http/cookies.d.ts.map +1 -0
  282. package/dist/types/http/errors.d.ts +36 -0
  283. package/dist/types/http/errors.d.ts.map +1 -0
  284. package/dist/types/http/handlers/authorize.d.ts +3 -0
  285. package/dist/types/http/handlers/authorize.d.ts.map +1 -0
  286. package/dist/types/http/handlers/callback.d.ts +3 -0
  287. package/dist/types/http/handlers/callback.d.ts.map +1 -0
  288. package/dist/types/http/handlers/metadata.d.ts +4 -0
  289. package/dist/types/http/handlers/metadata.d.ts.map +1 -0
  290. package/dist/types/http/handlers/method-route.d.ts +3 -0
  291. package/dist/types/http/handlers/method-route.d.ts.map +1 -0
  292. package/dist/types/http/handlers/revocation.d.ts +4 -0
  293. package/dist/types/http/handlers/revocation.d.ts.map +1 -0
  294. package/dist/types/http/handlers/token.d.ts +3 -0
  295. package/dist/types/http/handlers/token.d.ts.map +1 -0
  296. package/dist/types/http/handlers/userinfo.d.ts +3 -0
  297. package/dist/types/http/handlers/userinfo.d.ts.map +1 -0
  298. package/dist/types/http/middleware/error.d.ts +9 -0
  299. package/dist/types/http/middleware/error.d.ts.map +1 -0
  300. package/dist/types/http/middleware/tenant.d.ts +30 -0
  301. package/dist/types/http/middleware/tenant.d.ts.map +1 -0
  302. package/dist/types/http/resolver.d.ts +22 -0
  303. package/dist/types/http/resolver.d.ts.map +1 -0
  304. package/dist/types/http/router.d.ts +21 -0
  305. package/dist/types/http/router.d.ts.map +1 -0
  306. package/dist/types/http/schemas/authorize.d.ts +52 -0
  307. package/dist/types/http/schemas/authorize.d.ts.map +1 -0
  308. package/dist/types/http/schemas/revocation.d.ts +41 -0
  309. package/dist/types/http/schemas/revocation.d.ts.map +1 -0
  310. package/dist/types/http/schemas/token.d.ts +227 -0
  311. package/dist/types/http/schemas/token.d.ts.map +1 -0
  312. package/dist/types/index.d.ts +63 -13
  313. package/dist/types/index.d.ts.map +1 -1
  314. package/dist/types/methods/code.d.ts +96 -0
  315. package/dist/types/methods/code.d.ts.map +1 -0
  316. package/dist/types/methods/m2m.d.ts +41 -0
  317. package/dist/types/methods/m2m.d.ts.map +1 -0
  318. package/dist/types/methods/oauth2-factory.d.ts +133 -0
  319. package/dist/types/methods/oauth2-factory.d.ts.map +1 -0
  320. package/dist/types/methods/oauth2-generic.d.ts +75 -0
  321. package/dist/types/methods/oauth2-generic.d.ts.map +1 -0
  322. package/dist/types/methods/oidc-generic.d.ts +26 -0
  323. package/dist/types/methods/oidc-generic.d.ts.map +1 -0
  324. package/dist/types/methods/passkey.d.ts +106 -0
  325. package/dist/types/methods/passkey.d.ts.map +1 -0
  326. package/dist/types/methods/password-hash.d.ts +25 -0
  327. package/dist/types/methods/password-hash.d.ts.map +1 -0
  328. package/dist/types/methods/password.d.ts +70 -0
  329. package/dist/types/methods/password.d.ts.map +1 -0
  330. package/dist/types/methods/providers/apple.d.ts +29 -0
  331. package/dist/types/methods/providers/apple.d.ts.map +1 -0
  332. package/dist/types/methods/providers/cognito.d.ts +36 -0
  333. package/dist/types/methods/providers/cognito.d.ts.map +1 -0
  334. package/dist/types/methods/providers/discord.d.ts +22 -0
  335. package/dist/types/methods/providers/discord.d.ts.map +1 -0
  336. package/dist/types/methods/providers/facebook.d.ts +29 -0
  337. package/dist/types/methods/providers/facebook.d.ts.map +1 -0
  338. package/dist/types/methods/providers/github.d.ts +25 -0
  339. package/dist/types/methods/providers/github.d.ts.map +1 -0
  340. package/dist/types/methods/providers/google.d.ts +28 -0
  341. package/dist/types/methods/providers/google.d.ts.map +1 -0
  342. package/dist/types/methods/providers/index.d.ts +24 -0
  343. package/dist/types/methods/providers/index.d.ts.map +1 -0
  344. package/dist/types/methods/providers/jumpcloud.d.ts +22 -0
  345. package/dist/types/methods/providers/jumpcloud.d.ts.map +1 -0
  346. package/dist/types/methods/providers/keycloak.d.ts +30 -0
  347. package/dist/types/methods/providers/keycloak.d.ts.map +1 -0
  348. package/dist/types/methods/providers/linkedin.d.ts +22 -0
  349. package/dist/types/methods/providers/linkedin.d.ts.map +1 -0
  350. package/dist/types/methods/providers/microsoft.d.ts +30 -0
  351. package/dist/types/methods/providers/microsoft.d.ts.map +1 -0
  352. package/dist/types/methods/providers/slack.d.ts +25 -0
  353. package/dist/types/methods/providers/slack.d.ts.map +1 -0
  354. package/dist/types/methods/providers/spotify.d.ts +22 -0
  355. package/dist/types/methods/providers/spotify.d.ts.map +1 -0
  356. package/dist/types/methods/providers/twitch.d.ts +23 -0
  357. package/dist/types/methods/providers/twitch.d.ts.map +1 -0
  358. package/dist/types/methods/providers/x.d.ts +25 -0
  359. package/dist/types/methods/providers/x.d.ts.map +1 -0
  360. package/dist/types/methods/providers/yahoo.d.ts +22 -0
  361. package/dist/types/methods/providers/yahoo.d.ts.map +1 -0
  362. package/dist/types/pkce.d.ts +1 -2
  363. package/dist/types/pkce.d.ts.map +1 -1
  364. package/dist/types/ports/audit-log.d.ts +139 -0
  365. package/dist/types/ports/audit-log.d.ts.map +1 -0
  366. package/dist/types/ports/config-store.d.ts +32 -0
  367. package/dist/types/ports/config-store.d.ts.map +1 -0
  368. package/dist/types/ports/key-store.d.ts +98 -0
  369. package/dist/types/ports/key-store.d.ts.map +1 -0
  370. package/dist/types/ports/method-store.d.ts +29 -0
  371. package/dist/types/ports/method-store.d.ts.map +1 -0
  372. package/dist/types/ports/session-store.d.ts +82 -0
  373. package/dist/types/ports/session-store.d.ts.map +1 -0
  374. package/dist/types/ports/token-store.d.ts +93 -0
  375. package/dist/types/ports/token-store.d.ts.map +1 -0
  376. package/dist/types/types/authorization.d.ts +52 -0
  377. package/dist/types/types/authorization.d.ts.map +1 -0
  378. package/dist/types/types/error.d.ts +92 -0
  379. package/dist/types/types/error.d.ts.map +1 -0
  380. package/dist/types/types/flow.d.ts +87 -0
  381. package/dist/types/types/flow.d.ts.map +1 -0
  382. package/dist/types/types/idp.d.ts +234 -0
  383. package/dist/types/types/idp.d.ts.map +1 -0
  384. package/dist/types/types/method.d.ts +256 -0
  385. package/dist/types/types/method.d.ts.map +1 -0
  386. package/dist/types/types/picker.d.ts +31 -0
  387. package/dist/types/types/picker.d.ts.map +1 -0
  388. package/dist/types/types/result.d.ts +29 -0
  389. package/dist/types/types/result.d.ts.map +1 -0
  390. package/dist/types/types/subject.d.ts +47 -0
  391. package/dist/types/types/subject.d.ts.map +1 -0
  392. package/dist/types/types/tenant.d.ts +239 -0
  393. package/dist/types/types/tenant.d.ts.map +1 -0
  394. package/dist/types/types/token.d.ts +103 -0
  395. package/dist/types/types/token.d.ts.map +1 -0
  396. package/dist/types/ui/forms.d.ts +35 -0
  397. package/dist/types/ui/forms.d.ts.map +1 -0
  398. package/dist/types/ui/index.d.ts +14 -0
  399. package/dist/types/ui/index.d.ts.map +1 -0
  400. package/dist/types/ui/picker.d.ts +18 -0
  401. package/dist/types/ui/picker.d.ts.map +1 -0
  402. package/package.json +41 -6
  403. package/src/adapters/d1/audit-log.ts +32 -0
  404. package/src/adapters/d1/config-store.ts +67 -0
  405. package/src/adapters/d1/index.ts +41 -0
  406. package/src/adapters/d1/key-store.ts +218 -0
  407. package/src/adapters/d1/method-store.ts +103 -0
  408. package/src/adapters/d1/migrations.ts +89 -0
  409. package/src/adapters/d1/session-store.ts +230 -0
  410. package/src/adapters/d1/session.ts +38 -0
  411. package/src/adapters/d1/token-store.ts +251 -0
  412. package/src/adapters/d1/types.ts +53 -0
  413. package/src/adapters/durable-object/index.ts +23 -0
  414. package/src/adapters/durable-object/session-store.ts +227 -0
  415. package/src/adapters/durable-object/types.ts +25 -0
  416. package/src/adapters/dynamo/audit-log.ts +35 -0
  417. package/src/adapters/dynamo/client.ts +118 -0
  418. package/src/adapters/dynamo/config-store.ts +72 -0
  419. package/src/adapters/dynamo/index.ts +81 -0
  420. package/src/adapters/dynamo/key-store.ts +267 -0
  421. package/src/adapters/dynamo/method-store.ts +105 -0
  422. package/src/adapters/dynamo/passkey-credential-store.ts +132 -0
  423. package/src/adapters/dynamo/sdk.ts +189 -0
  424. package/src/adapters/dynamo/session-store.ts +229 -0
  425. package/src/adapters/dynamo/token-store.ts +248 -0
  426. package/src/adapters/kms/in-memory-backing.ts +36 -0
  427. package/src/adapters/kms/index.ts +39 -0
  428. package/src/adapters/kms/key-store.ts +176 -0
  429. package/src/adapters/kms/sdk.ts +39 -0
  430. package/src/adapters/kms/types.ts +61 -0
  431. package/src/adapters/kv/audit-log.ts +40 -0
  432. package/src/adapters/kv/config-store.ts +63 -0
  433. package/src/adapters/kv/index.ts +20 -0
  434. package/src/adapters/kv/method-store.ts +98 -0
  435. package/src/adapters/kv/types.ts +26 -0
  436. package/src/adapters/memory/audit-log.ts +28 -0
  437. package/src/adapters/memory/clock.ts +7 -0
  438. package/src/adapters/memory/config-store.ts +41 -0
  439. package/src/adapters/memory/index.ts +26 -0
  440. package/src/adapters/memory/key-store.ts +102 -0
  441. package/src/adapters/memory/method-store.ts +75 -0
  442. package/src/adapters/memory/passkey-credential-store.ts +97 -0
  443. package/src/adapters/memory/session-store.ts +128 -0
  444. package/src/adapters/memory/token-store.ts +165 -0
  445. package/src/adapters/postgres/audit-log.ts +34 -0
  446. package/src/adapters/postgres/config-store.ts +72 -0
  447. package/src/adapters/postgres/executor.ts +76 -0
  448. package/src/adapters/postgres/index.ts +60 -0
  449. package/src/adapters/postgres/key-store.ts +334 -0
  450. package/src/adapters/postgres/method-store.ts +104 -0
  451. package/src/adapters/postgres/migrations.ts +131 -0
  452. package/src/adapters/postgres/passkey-credential-store.ts +150 -0
  453. package/src/adapters/postgres/session-store.ts +216 -0
  454. package/src/adapters/postgres/token-store.ts +263 -0
  455. package/src/client.ts +50 -16
  456. package/src/domain/audit.ts +28 -0
  457. package/src/domain/authorize.ts +405 -0
  458. package/src/domain/callback.ts +263 -0
  459. package/src/domain/client-auth.ts +116 -0
  460. package/src/domain/client-credentials.ts +178 -0
  461. package/src/domain/crypto.ts +168 -0
  462. package/src/domain/discovery.ts +83 -0
  463. package/src/domain/introspect.ts +145 -0
  464. package/src/domain/jwt.ts +106 -0
  465. package/src/domain/method-cache.ts +220 -0
  466. package/src/domain/method-dispatch.ts +95 -0
  467. package/src/domain/method-route.ts +208 -0
  468. package/src/domain/pkce.ts +37 -0
  469. package/src/domain/refresh.ts +169 -0
  470. package/src/domain/revoke.ts +161 -0
  471. package/src/domain/state-envelope.ts +142 -0
  472. package/src/domain/token-exchange.ts +232 -0
  473. package/src/domain/token.ts +357 -0
  474. package/src/domain/userinfo.ts +56 -0
  475. package/src/http/context.ts +86 -0
  476. package/src/http/cookies.ts +167 -0
  477. package/src/http/errors.ts +98 -0
  478. package/src/http/handlers/authorize.ts +221 -0
  479. package/src/http/handlers/callback.ts +77 -0
  480. package/src/http/handlers/metadata.ts +44 -0
  481. package/src/http/handlers/method-route.ts +115 -0
  482. package/src/http/handlers/revocation.ts +151 -0
  483. package/src/http/handlers/token.ts +244 -0
  484. package/src/http/handlers/userinfo.ts +66 -0
  485. package/src/http/middleware/error.ts +26 -0
  486. package/src/http/middleware/tenant.ts +165 -0
  487. package/src/http/resolver.ts +34 -0
  488. package/src/http/router.ts +66 -0
  489. package/src/http/schemas/authorize.ts +58 -0
  490. package/src/http/schemas/revocation.ts +23 -0
  491. package/src/http/schemas/token.ts +85 -0
  492. package/src/index.ts +266 -20
  493. package/src/methods/code.ts +359 -0
  494. package/src/methods/m2m.ts +82 -0
  495. package/src/methods/oauth2-factory.ts +151 -0
  496. package/src/methods/oauth2-generic.ts +360 -0
  497. package/src/methods/oidc-generic.ts +109 -0
  498. package/src/methods/passkey.ts +419 -0
  499. package/src/methods/password-hash.ts +134 -0
  500. package/src/methods/password.ts +298 -0
  501. package/src/methods/providers/apple.ts +42 -0
  502. package/src/methods/providers/cognito.ts +55 -0
  503. package/src/methods/providers/discord.ts +37 -0
  504. package/src/methods/providers/facebook.ts +54 -0
  505. package/src/methods/providers/github.ts +42 -0
  506. package/src/methods/providers/google.ts +43 -0
  507. package/src/methods/providers/index.ts +23 -0
  508. package/src/methods/providers/jumpcloud.ts +36 -0
  509. package/src/methods/providers/keycloak.ts +42 -0
  510. package/src/methods/providers/linkedin.ts +37 -0
  511. package/src/methods/providers/microsoft.ts +42 -0
  512. package/src/methods/providers/slack.ts +42 -0
  513. package/src/methods/providers/spotify.ts +37 -0
  514. package/src/methods/providers/twitch.ts +38 -0
  515. package/src/methods/providers/x.ts +40 -0
  516. package/src/methods/providers/yahoo.ts +36 -0
  517. package/src/pkce.ts +20 -21
  518. package/src/ports/CONSISTENCY.md +88 -0
  519. package/src/ports/audit-log.ts +148 -0
  520. package/src/ports/config-store.ts +34 -0
  521. package/src/ports/key-store.ts +106 -0
  522. package/src/ports/method-store.ts +41 -0
  523. package/src/ports/session-store.ts +98 -0
  524. package/src/ports/token-store.ts +103 -0
  525. package/src/types/authorization.ts +53 -0
  526. package/src/types/error.ts +123 -0
  527. package/src/types/flow.ts +89 -0
  528. package/src/types/idp.ts +269 -0
  529. package/src/types/method.ts +270 -0
  530. package/src/types/picker.ts +32 -0
  531. package/src/types/result.ts +23 -0
  532. package/src/types/subject.ts +50 -0
  533. package/src/types/tenant.ts +248 -0
  534. package/src/types/token.ts +101 -0
  535. package/src/ui/forms.ts +289 -0
  536. package/src/ui/index.ts +14 -0
  537. package/src/ui/picker.ts +63 -0
  538. package/dist/esm/issuer.js +0 -691
  539. package/dist/esm/jwt.js +0 -16
  540. package/dist/esm/keys.js +0 -113
  541. package/dist/esm/provider/apple.js +0 -28
  542. package/dist/esm/provider/arctic.js +0 -43
  543. package/dist/esm/provider/code.js +0 -58
  544. package/dist/esm/provider/cognito.js +0 -16
  545. package/dist/esm/provider/discord.js +0 -15
  546. package/dist/esm/provider/facebook.js +0 -24
  547. package/dist/esm/provider/github.js +0 -15
  548. package/dist/esm/provider/google.js +0 -25
  549. package/dist/esm/provider/index.js +0 -3
  550. package/dist/esm/provider/jumpcloud.js +0 -15
  551. package/dist/esm/provider/keycloak.js +0 -15
  552. package/dist/esm/provider/linkedin.js +0 -15
  553. package/dist/esm/provider/m2m.js +0 -16
  554. package/dist/esm/provider/microsoft.js +0 -24
  555. package/dist/esm/provider/oauth2.js +0 -119
  556. package/dist/esm/provider/oidc.js +0 -69
  557. package/dist/esm/provider/passkey.js +0 -315
  558. package/dist/esm/provider/password.js +0 -306
  559. package/dist/esm/provider/provider.js +0 -10
  560. package/dist/esm/provider/slack.js +0 -15
  561. package/dist/esm/provider/spotify.js +0 -15
  562. package/dist/esm/provider/twitch.js +0 -15
  563. package/dist/esm/provider/x.js +0 -16
  564. package/dist/esm/provider/yahoo.js +0 -15
  565. package/dist/esm/random.js +0 -27
  566. package/dist/esm/storage/aws.js +0 -39
  567. package/dist/esm/storage/cloudflare.js +0 -42
  568. package/dist/esm/storage/dynamo.js +0 -116
  569. package/dist/esm/storage/memory.js +0 -88
  570. package/dist/esm/storage/storage.js +0 -36
  571. package/dist/esm/subject.js +0 -7
  572. package/dist/esm/ui/base.js +0 -407
  573. package/dist/esm/ui/code.js +0 -151
  574. package/dist/esm/ui/form.js +0 -43
  575. package/dist/esm/ui/icon.js +0 -92
  576. package/dist/esm/ui/passkey.js +0 -329
  577. package/dist/esm/ui/password.js +0 -338
  578. package/dist/esm/ui/select.js +0 -187
  579. package/dist/esm/ui/theme.js +0 -115
  580. package/dist/esm/util.js +0 -54
  581. package/dist/types/issuer.d.ts +0 -607
  582. package/dist/types/issuer.d.ts.map +0 -1
  583. package/dist/types/jwt.d.ts +0 -6
  584. package/dist/types/jwt.d.ts.map +0 -1
  585. package/dist/types/keys.d.ts +0 -18
  586. package/dist/types/keys.d.ts.map +0 -1
  587. package/dist/types/provider/apple.d.ts +0 -108
  588. package/dist/types/provider/apple.d.ts.map +0 -1
  589. package/dist/types/provider/arctic.d.ts +0 -16
  590. package/dist/types/provider/arctic.d.ts.map +0 -1
  591. package/dist/types/provider/code.d.ts +0 -74
  592. package/dist/types/provider/code.d.ts.map +0 -1
  593. package/dist/types/provider/cognito.d.ts +0 -64
  594. package/dist/types/provider/cognito.d.ts.map +0 -1
  595. package/dist/types/provider/discord.d.ts +0 -38
  596. package/dist/types/provider/discord.d.ts.map +0 -1
  597. package/dist/types/provider/facebook.d.ts +0 -74
  598. package/dist/types/provider/facebook.d.ts.map +0 -1
  599. package/dist/types/provider/github.d.ts +0 -38
  600. package/dist/types/provider/github.d.ts.map +0 -1
  601. package/dist/types/provider/google.d.ts +0 -74
  602. package/dist/types/provider/google.d.ts.map +0 -1
  603. package/dist/types/provider/index.d.ts +0 -4
  604. package/dist/types/provider/index.d.ts.map +0 -1
  605. package/dist/types/provider/jumpcloud.d.ts +0 -38
  606. package/dist/types/provider/jumpcloud.d.ts.map +0 -1
  607. package/dist/types/provider/keycloak.d.ts +0 -67
  608. package/dist/types/provider/keycloak.d.ts.map +0 -1
  609. package/dist/types/provider/linkedin.d.ts +0 -6
  610. package/dist/types/provider/linkedin.d.ts.map +0 -1
  611. package/dist/types/provider/m2m.d.ts +0 -34
  612. package/dist/types/provider/m2m.d.ts.map +0 -1
  613. package/dist/types/provider/microsoft.d.ts +0 -89
  614. package/dist/types/provider/microsoft.d.ts.map +0 -1
  615. package/dist/types/provider/oauth2.d.ts +0 -133
  616. package/dist/types/provider/oauth2.d.ts.map +0 -1
  617. package/dist/types/provider/oidc.d.ts +0 -91
  618. package/dist/types/provider/oidc.d.ts.map +0 -1
  619. package/dist/types/provider/passkey.d.ts +0 -143
  620. package/dist/types/provider/passkey.d.ts.map +0 -1
  621. package/dist/types/provider/password.d.ts +0 -210
  622. package/dist/types/provider/password.d.ts.map +0 -1
  623. package/dist/types/provider/provider.d.ts +0 -29
  624. package/dist/types/provider/provider.d.ts.map +0 -1
  625. package/dist/types/provider/slack.d.ts +0 -59
  626. package/dist/types/provider/slack.d.ts.map +0 -1
  627. package/dist/types/provider/spotify.d.ts +0 -38
  628. package/dist/types/provider/spotify.d.ts.map +0 -1
  629. package/dist/types/provider/twitch.d.ts +0 -38
  630. package/dist/types/provider/twitch.d.ts.map +0 -1
  631. package/dist/types/provider/x.d.ts +0 -38
  632. package/dist/types/provider/x.d.ts.map +0 -1
  633. package/dist/types/provider/yahoo.d.ts +0 -38
  634. package/dist/types/provider/yahoo.d.ts.map +0 -1
  635. package/dist/types/random.d.ts +0 -3
  636. package/dist/types/random.d.ts.map +0 -1
  637. package/dist/types/storage/aws.d.ts +0 -4
  638. package/dist/types/storage/aws.d.ts.map +0 -1
  639. package/dist/types/storage/cloudflare.d.ts +0 -34
  640. package/dist/types/storage/cloudflare.d.ts.map +0 -1
  641. package/dist/types/storage/dynamo.d.ts +0 -65
  642. package/dist/types/storage/dynamo.d.ts.map +0 -1
  643. package/dist/types/storage/memory.d.ts +0 -49
  644. package/dist/types/storage/memory.d.ts.map +0 -1
  645. package/dist/types/storage/storage.d.ts +0 -15
  646. package/dist/types/storage/storage.d.ts.map +0 -1
  647. package/dist/types/subject.d.ts +0 -122
  648. package/dist/types/subject.d.ts.map +0 -1
  649. package/dist/types/ui/base.d.ts +0 -5
  650. package/dist/types/ui/base.d.ts.map +0 -1
  651. package/dist/types/ui/code.d.ts +0 -104
  652. package/dist/types/ui/code.d.ts.map +0 -1
  653. package/dist/types/ui/form.d.ts +0 -6
  654. package/dist/types/ui/form.d.ts.map +0 -1
  655. package/dist/types/ui/icon.d.ts +0 -6
  656. package/dist/types/ui/icon.d.ts.map +0 -1
  657. package/dist/types/ui/passkey.d.ts +0 -5
  658. package/dist/types/ui/passkey.d.ts.map +0 -1
  659. package/dist/types/ui/password.d.ts +0 -139
  660. package/dist/types/ui/password.d.ts.map +0 -1
  661. package/dist/types/ui/select.d.ts +0 -55
  662. package/dist/types/ui/select.d.ts.map +0 -1
  663. package/dist/types/ui/theme.d.ts +0 -207
  664. package/dist/types/ui/theme.d.ts.map +0 -1
  665. package/dist/types/util.d.ts +0 -8
  666. package/dist/types/util.d.ts.map +0 -1
  667. package/src/css.d.ts +0 -4
  668. package/src/issuer.ts +0 -1628
  669. package/src/jwt.ts +0 -17
  670. package/src/keys.ts +0 -139
  671. package/src/provider/apple.ts +0 -127
  672. package/src/provider/arctic.ts +0 -66
  673. package/src/provider/code.ts +0 -227
  674. package/src/provider/cognito.ts +0 -74
  675. package/src/provider/discord.ts +0 -45
  676. package/src/provider/facebook.ts +0 -84
  677. package/src/provider/github.ts +0 -45
  678. package/src/provider/google.ts +0 -85
  679. package/src/provider/index.ts +0 -3
  680. package/src/provider/jumpcloud.ts +0 -45
  681. package/src/provider/keycloak.ts +0 -75
  682. package/src/provider/linkedin.ts +0 -12
  683. package/src/provider/m2m.ts +0 -56
  684. package/src/provider/microsoft.ts +0 -100
  685. package/src/provider/oauth2.ts +0 -297
  686. package/src/provider/oidc.ts +0 -179
  687. package/src/provider/passkey.ts +0 -655
  688. package/src/provider/password.ts +0 -672
  689. package/src/provider/provider.ts +0 -33
  690. package/src/provider/slack.ts +0 -67
  691. package/src/provider/spotify.ts +0 -45
  692. package/src/provider/twitch.ts +0 -45
  693. package/src/provider/x.ts +0 -46
  694. package/src/provider/yahoo.ts +0 -45
  695. package/src/random.ts +0 -24
  696. package/src/storage/aws.ts +0 -59
  697. package/src/storage/cloudflare.ts +0 -77
  698. package/src/storage/dynamo.ts +0 -193
  699. package/src/storage/memory.ts +0 -135
  700. package/src/storage/storage.ts +0 -46
  701. package/src/subject.ts +0 -130
  702. package/src/ui/base.tsx +0 -118
  703. package/src/ui/code.tsx +0 -215
  704. package/src/ui/form.tsx +0 -40
  705. package/src/ui/icon.tsx +0 -95
  706. package/src/ui/passkey.tsx +0 -321
  707. package/src/ui/password.tsx +0 -405
  708. package/src/ui/select.tsx +0 -221
  709. package/src/ui/theme.ts +0 -319
  710. package/src/ui/ui.css +0 -252
  711. package/src/util.ts +0 -58
  712. /package/dist/esm/{css.d.js → adapters/d1/types.js} +0 -0
@@ -0,0 +1,419 @@
1
+ /**
2
+ * `passkeyMethod` — WebAuthn factory using `@simplewebauthn/server`.
3
+ *
4
+ * Routes:
5
+ * GET /authorize → render the username form.
6
+ * POST /authenticate-options → mint challenge, return PublicKeyCredentialRequestOptionsJSON.
7
+ * POST /authenticate-verify → verify assertion, return success.
8
+ * POST /register-options → mint registration challenge, return options.
9
+ * POST /register-verify → verify attestation, persist credential.
10
+ *
11
+ * The framework knows nothing about credentials; the tenant supplies a
12
+ * `credentials` store. The method calls into it for lookups + writes. The
13
+ * RP id and origin are configured per factory at build time; multi-domain
14
+ * tenants instantiate multiple factories with distinct ids.
15
+ *
16
+ * Phase 4 ships the authentication ceremony end-to-end and exposes the
17
+ * registration helpers so the management console (Phase 7) can wire them
18
+ * up. Full registration UI / passkey enrollment flow polishes lands with
19
+ * the console.
20
+ */
21
+ import { z } from "zod"
22
+ import {
23
+ generateAuthenticationOptions,
24
+ generateRegistrationOptions,
25
+ verifyAuthenticationResponse,
26
+ verifyRegistrationResponse,
27
+ } from "@simplewebauthn/server"
28
+
29
+ import type {
30
+ AuthMethod,
31
+ AuthMethodFactory,
32
+ MethodContext,
33
+ MethodResult,
34
+ } from "../types/method"
35
+ import { renderForm } from "../ui/forms"
36
+
37
+ export type PasskeyProperties = {
38
+ userId: string
39
+ credentialId: string
40
+ }
41
+
42
+ export type StoredCredential = {
43
+ /** Base64url credential id. */
44
+ credentialId: string
45
+ /** Base64url public key. */
46
+ publicKey: string
47
+ /** WebAuthn signature counter for replay protection. */
48
+ counter: number
49
+ /** Optional transports hint stored at registration. */
50
+ transports?: string[]
51
+ userId: string
52
+ }
53
+
54
+ export type PasskeyCredentialStore = {
55
+ findByUsername(
56
+ username: string,
57
+ tenantId: string,
58
+ ): Promise<{ userId: string; credentials: StoredCredential[] } | null>
59
+ findById(
60
+ credentialId: string,
61
+ tenantId: string,
62
+ ): Promise<StoredCredential | null>
63
+ /** Update the signature counter after a successful verification. */
64
+ updateCounter(input: {
65
+ credentialId: string
66
+ counter: number
67
+ tenantId: string
68
+ }): Promise<void>
69
+ /** Persist a newly-registered credential. */
70
+ create?(input: {
71
+ userId: string
72
+ credential: StoredCredential
73
+ tenantId: string
74
+ }): Promise<void>
75
+ }
76
+
77
+ export type PasskeyMethodOptions = {
78
+ /**
79
+ * Tenant-supplied credential store. The framework calls into it for
80
+ * lookups + writes; it knows nothing about how credentials are stored.
81
+ */
82
+ credentials: PasskeyCredentialStore
83
+ }
84
+
85
+ export type PasskeyState =
86
+ | { phase: "auth"; challenge: string; username: string }
87
+ | { phase: "register"; challenge: string; userId: string; username: string }
88
+
89
+ /**
90
+ * Per-tenant config. `rpID` is the WebAuthn Relying Party ID (the
91
+ * registrable domain — e.g. `"acme.example"`); each tenant typically
92
+ * runs on its own domain so this is per-tenant, not per-factory.
93
+ *
94
+ * `origins` is the list of accepted browser origins (HTTPS URLs).
95
+ * Multi-origin support is useful for tenants with both an app subdomain
96
+ * and a marketing domain that both terminate at the IdP.
97
+ */
98
+ const configSchema = z.object({
99
+ /** Display name shown by the authenticator UI. */
100
+ rpName: z.string().min(1),
101
+ /** Relying Party ID — the registrable domain. */
102
+ rpID: z.string().min(1),
103
+ /** Accepted origin(s). Either a single URL or an array of URLs. */
104
+ origins: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]),
105
+ /** Form title override. */
106
+ title: z.string().optional(),
107
+ })
108
+ type PasskeyConfig = z.infer<typeof configSchema>
109
+
110
+ /**
111
+ * Resolved per-instance settings threaded into route handlers. We
112
+ * collapse the union shape of `origins` into the array shape
113
+ * `@simplewebauthn/server` accepts.
114
+ */
115
+ type PasskeySettings = {
116
+ rpName: string
117
+ rpID: string
118
+ origin: string | string[]
119
+ title: string
120
+ credentials: PasskeyCredentialStore
121
+ }
122
+
123
+ const usernameBody = z.object({ username: z.string().min(1) })
124
+ const verifyBody = z.object({ response: z.string().min(1) })
125
+
126
+ export function passkeyMethod(
127
+ opts: PasskeyMethodOptions,
128
+ ): AuthMethodFactory<PasskeyProperties, PasskeyState, PasskeyConfig> {
129
+ return {
130
+ kind: "passkey",
131
+ configSchema,
132
+ build: async ({
133
+ id,
134
+ kind,
135
+ config,
136
+ }): Promise<AuthMethod<PasskeyProperties, PasskeyState>> => {
137
+ const settings: PasskeySettings = {
138
+ rpName: config.rpName,
139
+ rpID: config.rpID,
140
+ origin: config.origins,
141
+ title: config.title ?? "Sign in with passkey",
142
+ credentials: opts.credentials,
143
+ }
144
+ return {
145
+ id,
146
+ kind,
147
+ type: "passkey",
148
+ routes: {
149
+ "GET /authorize": async () => ({
150
+ kind: "challenge",
151
+ response: htmlResponse(
152
+ renderForm({
153
+ title: settings.title,
154
+ action: `/m/${id}/authenticate-options`,
155
+ fields: [
156
+ {
157
+ name: "username",
158
+ label: "Username",
159
+ required: true,
160
+ autocomplete: "username webauthn",
161
+ },
162
+ ],
163
+ submit: "Continue",
164
+ }),
165
+ ),
166
+ }),
167
+ "POST /authenticate-options": async (ctx) =>
168
+ authOptions(ctx, settings),
169
+ "POST /authenticate-verify": async (ctx) => authVerify(ctx, settings),
170
+ "POST /register-options": async (ctx) =>
171
+ registerOptions(ctx, id, settings),
172
+ "POST /register-verify": async (ctx) => registerVerify(ctx, settings),
173
+ },
174
+ }
175
+ },
176
+ }
177
+ }
178
+
179
+ async function authOptions(
180
+ ctx: MethodContext<PasskeyState>,
181
+ settings: PasskeySettings,
182
+ ): Promise<MethodResult<PasskeyProperties, PasskeyState>> {
183
+ const form = await safeForm(ctx.request)
184
+ const parsed = usernameBody.safeParse(form)
185
+ if (!parsed.success) {
186
+ return errorResult("missing username")
187
+ }
188
+ const found = await settings.credentials.findByUsername(
189
+ parsed.data.username,
190
+ ctx.tenant.id,
191
+ )
192
+ if (!found) {
193
+ return errorResult("unknown user")
194
+ }
195
+ const options = await generateAuthenticationOptions({
196
+ rpID: settings.rpID,
197
+ allowCredentials: found.credentials.map((c) => ({
198
+ id: c.credentialId,
199
+ ...(c.transports ? { transports: c.transports as never } : {}),
200
+ })),
201
+ userVerification: "preferred",
202
+ })
203
+ return {
204
+ kind: "challenge",
205
+ response: jsonResponse(options),
206
+ saveMethodState: {
207
+ phase: "auth",
208
+ challenge: options.challenge,
209
+ username: parsed.data.username,
210
+ },
211
+ }
212
+ }
213
+
214
+ async function authVerify(
215
+ ctx: MethodContext<PasskeyState>,
216
+ settings: PasskeySettings,
217
+ ): Promise<MethodResult<PasskeyProperties, PasskeyState>> {
218
+ if (!ctx.methodState || ctx.methodState.phase !== "auth") {
219
+ return errorResult("verify without prior /authenticate-options")
220
+ }
221
+ const state = ctx.methodState
222
+ const form = await safeForm(ctx.request)
223
+ const parsed = verifyBody.safeParse(form)
224
+ if (!parsed.success) return errorResult("missing response")
225
+
226
+ let assertion
227
+ try {
228
+ assertion = JSON.parse(parsed.data.response)
229
+ } catch {
230
+ return errorResult("malformed WebAuthn response")
231
+ }
232
+ const credentialId = assertion?.id as string | undefined
233
+ if (!credentialId) return errorResult("missing credential id")
234
+ const stored = await settings.credentials.findById(
235
+ credentialId,
236
+ ctx.tenant.id,
237
+ )
238
+ if (!stored) return errorResult("unknown credential")
239
+
240
+ let verification
241
+ try {
242
+ verification = await verifyAuthenticationResponse({
243
+ response: assertion,
244
+ expectedChallenge: state.challenge,
245
+ expectedOrigin: settings.origin,
246
+ expectedRPID: settings.rpID,
247
+ credential: {
248
+ id: stored.credentialId,
249
+ publicKey: base64urlDecode(stored.publicKey),
250
+ counter: stored.counter,
251
+ ...(stored.transports
252
+ ? { transports: stored.transports as never }
253
+ : {}),
254
+ },
255
+ })
256
+ } catch (e) {
257
+ return errorResult(e instanceof Error ? e.message : "verification threw")
258
+ }
259
+ if (!verification.verified) {
260
+ return errorResult("verification rejected")
261
+ }
262
+ await settings.credentials.updateCounter({
263
+ credentialId: stored.credentialId,
264
+ counter: verification.authenticationInfo.newCounter,
265
+ tenantId: ctx.tenant.id,
266
+ })
267
+
268
+ return {
269
+ kind: "success",
270
+ providerSubject: stored.userId,
271
+ properties: { userId: stored.userId, credentialId: stored.credentialId },
272
+ }
273
+ }
274
+
275
+ async function registerOptions(
276
+ ctx: MethodContext<PasskeyState>,
277
+ _methodId: string,
278
+ settings: PasskeySettings,
279
+ ): Promise<MethodResult<PasskeyProperties, PasskeyState>> {
280
+ if (!settings.credentials.create) {
281
+ return errorResult("registration not enabled")
282
+ }
283
+ const form = await safeForm(ctx.request)
284
+ const parsed = usernameBody.safeParse(form)
285
+ if (!parsed.success) return errorResult("missing username")
286
+
287
+ const userId = parsed.data.username
288
+ const options = await generateRegistrationOptions({
289
+ rpName: settings.rpName,
290
+ rpID: settings.rpID,
291
+ userName: parsed.data.username,
292
+ userID: new TextEncoder().encode(userId),
293
+ attestationType: "none",
294
+ authenticatorSelection: {
295
+ residentKey: "preferred",
296
+ userVerification: "preferred",
297
+ },
298
+ })
299
+ return {
300
+ kind: "challenge",
301
+ response: jsonResponse(options),
302
+ saveMethodState: {
303
+ phase: "register",
304
+ challenge: options.challenge,
305
+ userId,
306
+ username: parsed.data.username,
307
+ },
308
+ }
309
+ }
310
+
311
+ async function registerVerify(
312
+ ctx: MethodContext<PasskeyState>,
313
+ settings: PasskeySettings,
314
+ ): Promise<MethodResult<PasskeyProperties, PasskeyState>> {
315
+ if (!settings.credentials.create) {
316
+ return errorResult("registration not enabled")
317
+ }
318
+ if (!ctx.methodState || ctx.methodState.phase !== "register") {
319
+ return errorResult("verify without prior /register-options")
320
+ }
321
+ const state = ctx.methodState
322
+ const form = await safeForm(ctx.request)
323
+ const parsed = verifyBody.safeParse(form)
324
+ if (!parsed.success) return errorResult("missing response")
325
+ let attestation
326
+ try {
327
+ attestation = JSON.parse(parsed.data.response)
328
+ } catch {
329
+ return errorResult("malformed WebAuthn attestation")
330
+ }
331
+
332
+ let verification
333
+ try {
334
+ verification = await verifyRegistrationResponse({
335
+ response: attestation,
336
+ expectedChallenge: state.challenge,
337
+ expectedOrigin: settings.origin,
338
+ expectedRPID: settings.rpID,
339
+ requireUserVerification: false,
340
+ })
341
+ } catch (e) {
342
+ return errorResult(e instanceof Error ? e.message : "verification threw")
343
+ }
344
+ if (!verification.verified || !verification.registrationInfo) {
345
+ return errorResult("registration rejected")
346
+ }
347
+ const reg = verification.registrationInfo
348
+ await settings.credentials.create({
349
+ userId: state.userId,
350
+ credential: {
351
+ credentialId: reg.credential.id,
352
+ publicKey: base64urlEncode(reg.credential.publicKey),
353
+ counter: reg.credential.counter,
354
+ ...(reg.credential.transports
355
+ ? { transports: reg.credential.transports as string[] }
356
+ : {}),
357
+ userId: state.userId,
358
+ },
359
+ tenantId: ctx.tenant.id,
360
+ })
361
+ return {
362
+ kind: "success",
363
+ providerSubject: state.userId,
364
+ properties: { userId: state.userId, credentialId: reg.credential.id },
365
+ }
366
+ }
367
+
368
+ function errorResult(
369
+ description: string,
370
+ ): MethodResult<PasskeyProperties, PasskeyState> {
371
+ return {
372
+ kind: "error",
373
+ error: { code: "invalid_request", description },
374
+ }
375
+ }
376
+
377
+ async function safeForm(req: Request): Promise<Record<string, string>> {
378
+ const ct = req.headers.get("content-type") ?? ""
379
+ if (ct.toLowerCase().startsWith("application/x-www-form-urlencoded")) {
380
+ return Object.fromEntries(new URLSearchParams(await req.text()).entries())
381
+ }
382
+ if (ct.toLowerCase().startsWith("application/json")) {
383
+ try {
384
+ return (await req.json()) as Record<string, string>
385
+ } catch {
386
+ return {}
387
+ }
388
+ }
389
+ return {}
390
+ }
391
+
392
+ function htmlResponse(body: string, status = 200): Response {
393
+ return new Response(body, {
394
+ status,
395
+ headers: { "content-type": "text/html; charset=utf-8" },
396
+ })
397
+ }
398
+
399
+ function jsonResponse(body: unknown, status = 200): Response {
400
+ return new Response(JSON.stringify(body), {
401
+ status,
402
+ headers: { "content-type": "application/json" },
403
+ })
404
+ }
405
+
406
+ function base64urlEncode(bytes: Uint8Array): string {
407
+ let s = ""
408
+ for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]!)
409
+ return btoa(s).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "")
410
+ }
411
+
412
+ function base64urlDecode(s: string): Uint8Array {
413
+ const pad = s.length % 4 === 0 ? 0 : 4 - (s.length % 4)
414
+ const b64 = (s + "=".repeat(pad)).replace(/-/g, "+").replace(/_/g, "/")
415
+ const bin = atob(b64)
416
+ const out = new Uint8Array(bin.length)
417
+ for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i)
418
+ return out
419
+ }
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Pluggable password hasher.
3
+ *
4
+ * Default: **argon2id** (RFC 9106, OWASP 2024 recommendation) via
5
+ * `@noble/hashes/argon2`. Pure JS, edge-compatible, no native deps.
6
+ *
7
+ * Tuning defaults follow the RFC 9106 §4 second recommended setting
8
+ * (`t=3, m=64 MiB, p=4`). Operators with tight memory budgets (edge
9
+ * platforms with strict per-request memory caps) can swap in their own
10
+ * hasher via `passwordMethod({ hasher: customHasher })`.
11
+ *
12
+ * The serialized hash format is the canonical PHC string
13
+ * (`$argon2id$v=19$m=65536,t=3,p=4$<salt>$<hash>`) so users can verify
14
+ * existing hashes from any conforming implementation.
15
+ */
16
+ import { argon2idAsync } from "@noble/hashes/argon2.js"
17
+
18
+ import {
19
+ base64url,
20
+ randomBytes,
21
+ timingSafeEqualStr,
22
+ utf8,
23
+ } from "../domain/crypto"
24
+
25
+ export type PasswordHasher = {
26
+ /** Hash the password; output includes salt + parameters. */
27
+ hash(plain: string): Promise<string>
28
+ /** Verify a plain password against a previously stored hash. */
29
+ verify(plain: string, stored: string): Promise<boolean>
30
+ }
31
+
32
+ export type Argon2idParams = {
33
+ /** Time cost. RFC 9106 §4 recommends `t=3` for the 64 MiB profile. */
34
+ t: number
35
+ /** Memory cost in KiB. RFC 9106 §4 recommends `65536` (64 MiB). */
36
+ m: number
37
+ /** Parallelism. RFC 9106 §4 recommends `4`. */
38
+ p: number
39
+ /** Output length in bytes. 32 is standard. */
40
+ dkLen: number
41
+ /** Salt length in bytes. 16 is the RFC 9106 minimum. */
42
+ saltLen: number
43
+ }
44
+
45
+ export const DEFAULT_ARGON2ID_PARAMS: Argon2idParams = {
46
+ t: 3,
47
+ m: 65536,
48
+ p: 4,
49
+ dkLen: 32,
50
+ saltLen: 16,
51
+ }
52
+
53
+ /**
54
+ * Build an argon2id `PasswordHasher`. Stored hashes use the canonical PHC
55
+ * string format so they're interoperable with any RFC 9106 implementation.
56
+ */
57
+ export function argon2idHasher(
58
+ params: Partial<Argon2idParams> = {},
59
+ ): PasswordHasher {
60
+ const cfg = { ...DEFAULT_ARGON2ID_PARAMS, ...params }
61
+ return {
62
+ async hash(plain: string): Promise<string> {
63
+ const salt = randomBytes(cfg.saltLen)
64
+ const out = await argon2idAsync(utf8.encode(plain), salt, {
65
+ t: cfg.t,
66
+ m: cfg.m,
67
+ p: cfg.p,
68
+ dkLen: cfg.dkLen,
69
+ })
70
+ return `$argon2id$v=19$m=${cfg.m},t=${cfg.t},p=${cfg.p}$${base64url.encode(salt)}$${base64url.encode(out as Uint8Array)}`
71
+ },
72
+ async verify(plain: string, stored: string): Promise<boolean> {
73
+ const parsed = parsePhc(stored)
74
+ if (!parsed) return false
75
+ if (parsed.algo !== "argon2id") return false
76
+ try {
77
+ const out = await argon2idAsync(utf8.encode(plain), parsed.salt, {
78
+ t: parsed.t,
79
+ m: parsed.m,
80
+ p: parsed.p,
81
+ dkLen: parsed.hash.length,
82
+ })
83
+ return timingSafeEqualStr(
84
+ base64url.encode(out as Uint8Array),
85
+ base64url.encode(parsed.hash),
86
+ )
87
+ } catch {
88
+ return false
89
+ }
90
+ },
91
+ }
92
+ }
93
+
94
+ type Phc = {
95
+ algo: string
96
+ t: number
97
+ m: number
98
+ p: number
99
+ salt: Uint8Array
100
+ hash: Uint8Array
101
+ }
102
+
103
+ function parsePhc(stored: string): Phc | null {
104
+ // Format: $algo$v=19$m=N,t=N,p=N$<saltb64u>$<hashb64u>
105
+ const parts = stored.split("$")
106
+ if (parts.length !== 6) return null
107
+ const [, algo, _version, params, saltStr, hashStr] = parts
108
+ if (!algo || !params || !saltStr || !hashStr) return null
109
+ const kv = Object.fromEntries(
110
+ params.split(",").map((p) => {
111
+ const [k, v] = p.split("=")
112
+ return [k ?? "", Number.parseInt(v ?? "0", 10)]
113
+ }),
114
+ )
115
+ if (
116
+ typeof kv.m !== "number" ||
117
+ typeof kv.t !== "number" ||
118
+ typeof kv.p !== "number"
119
+ ) {
120
+ return null
121
+ }
122
+ try {
123
+ return {
124
+ algo,
125
+ t: kv.t,
126
+ m: kv.m,
127
+ p: kv.p,
128
+ salt: base64url.decode(saltStr),
129
+ hash: base64url.decode(hashStr),
130
+ }
131
+ } catch {
132
+ return null
133
+ }
134
+ }