@_mustachio/openauth 0.9.2 → 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,150 @@
1
+ /**
2
+ * Postgres `PasskeyCredentialStore`.
3
+ *
4
+ * Schema (created by `migrate()` in `./migrations.ts`):
5
+ *
6
+ * openauth_passkey_credentials
7
+ * tenant_id text NOT NULL
8
+ * credential_id text NOT NULL
9
+ * user_id text NOT NULL
10
+ * public_key text NOT NULL
11
+ * counter bigint NOT NULL DEFAULT 0
12
+ * transports jsonb
13
+ * created_at bigint NOT NULL
14
+ * PRIMARY KEY (tenant_id, credential_id)
15
+ * INDEX (tenant_id, user_id) -- findByUsername path
16
+ *
17
+ * The reference adapter treats `userId` as the username lookup key —
18
+ * matching the bundled `passkeyMethod` which sets `userId =
19
+ * parsed.data.username` at registration. Hosts that want a separate
20
+ * username dimension implement `PasskeyCredentialStore` directly
21
+ * against their own user table.
22
+ */
23
+ import type {
24
+ PasskeyCredentialStore,
25
+ StoredCredential,
26
+ } from "../../methods/passkey"
27
+
28
+ import type { PostgresExecutor } from "./executor"
29
+
30
+ export type PostgresPasskeyCredentialStoreOptions = {
31
+ exec: PostgresExecutor
32
+ clock?: () => number
33
+ }
34
+
35
+ type Row = {
36
+ credential_id: string
37
+ user_id: string
38
+ public_key: string
39
+ counter: string | number
40
+ transports: unknown
41
+ }
42
+
43
+ export class PostgresPasskeyCredentialStore implements PasskeyCredentialStore {
44
+ #exec: PostgresExecutor
45
+ #clock: () => number
46
+
47
+ constructor(opts: PostgresPasskeyCredentialStoreOptions) {
48
+ this.#exec = opts.exec
49
+ this.#clock = opts.clock ?? (() => Date.now())
50
+ }
51
+
52
+ async findByUsername(
53
+ username: string,
54
+ tenantId: string,
55
+ ): Promise<{ userId: string; credentials: StoredCredential[] } | null> {
56
+ const result = await this.#exec.query<Row>(
57
+ `SELECT credential_id, user_id, public_key, counter, transports
58
+ FROM openauth_passkey_credentials
59
+ WHERE tenant_id = $1 AND user_id = $2`,
60
+ [tenantId, username],
61
+ )
62
+ if (result.rows.length === 0) return null
63
+ return {
64
+ userId: username,
65
+ credentials: result.rows.map(rowToCredential),
66
+ }
67
+ }
68
+
69
+ async findById(
70
+ credentialId: string,
71
+ tenantId: string,
72
+ ): Promise<StoredCredential | null> {
73
+ const result = await this.#exec.query<Row>(
74
+ `SELECT credential_id, user_id, public_key, counter, transports
75
+ FROM openauth_passkey_credentials
76
+ WHERE tenant_id = $1 AND credential_id = $2`,
77
+ [tenantId, credentialId],
78
+ )
79
+ const row = result.rows[0]
80
+ if (!row) return null
81
+ return rowToCredential(row)
82
+ }
83
+
84
+ async updateCounter(input: {
85
+ credentialId: string
86
+ counter: number
87
+ tenantId: string
88
+ }): Promise<void> {
89
+ await this.#exec.query(
90
+ `UPDATE openauth_passkey_credentials
91
+ SET counter = $1
92
+ WHERE tenant_id = $2 AND credential_id = $3`,
93
+ [input.counter, input.tenantId, input.credentialId],
94
+ )
95
+ }
96
+
97
+ async create(input: {
98
+ userId: string
99
+ credential: StoredCredential
100
+ tenantId: string
101
+ }): Promise<void> {
102
+ await this.#exec.query(
103
+ `INSERT INTO openauth_passkey_credentials
104
+ (tenant_id, credential_id, user_id, public_key, counter, transports, created_at)
105
+ VALUES ($1, $2, $3, $4, $5, $6::jsonb, $7)
106
+ ON CONFLICT (tenant_id, credential_id) DO UPDATE
107
+ SET public_key = EXCLUDED.public_key,
108
+ counter = EXCLUDED.counter,
109
+ transports = EXCLUDED.transports,
110
+ user_id = EXCLUDED.user_id`,
111
+ [
112
+ input.tenantId,
113
+ input.credential.credentialId,
114
+ input.userId,
115
+ input.credential.publicKey,
116
+ input.credential.counter,
117
+ input.credential.transports
118
+ ? JSON.stringify(input.credential.transports)
119
+ : null,
120
+ this.#clock(),
121
+ ],
122
+ )
123
+ }
124
+ }
125
+
126
+ function rowToCredential(row: Row): StoredCredential {
127
+ const credential: StoredCredential = {
128
+ credentialId: row.credential_id,
129
+ publicKey: row.public_key,
130
+ counter: Number(row.counter),
131
+ userId: row.user_id,
132
+ }
133
+ if (row.transports != null) {
134
+ credential.transports = parseTransports(row.transports)
135
+ }
136
+ return credential
137
+ }
138
+
139
+ function parseTransports(raw: unknown): string[] {
140
+ if (Array.isArray(raw)) return raw.map(String)
141
+ if (typeof raw === "string") {
142
+ try {
143
+ const parsed: unknown = JSON.parse(raw)
144
+ return Array.isArray(parsed) ? parsed.map(String) : []
145
+ } catch {
146
+ return []
147
+ }
148
+ }
149
+ return []
150
+ }
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Postgres `SessionStore` — flow records + optional long-lived sessions.
3
+ *
4
+ * `consumeFlow` is `DELETE … RETURNING payload, expires_at` — atomic
5
+ * single-winner, returns the full record so the framework can snapshot
6
+ * fields into the auth-code payload before disposal.
7
+ *
8
+ * `updateFlowMethodState` merges new state into the existing JSONB blob via
9
+ * a single UPDATE (no read-modify-write race).
10
+ */
11
+ import { authError } from "../../types/error"
12
+ import type { FlowRecord } from "../../types/flow"
13
+ import type { SessionRecord, SessionStore } from "../../ports/session-store"
14
+ import type { Result } from "../../types/result"
15
+ import { err, ok } from "../../types/result"
16
+
17
+ import type { PostgresExecutor } from "./executor"
18
+
19
+ export type PostgresSessionStoreOptions = {
20
+ exec: PostgresExecutor
21
+ clock?: () => number
22
+ }
23
+
24
+ export class PostgresSessionStore implements SessionStore {
25
+ #exec: PostgresExecutor
26
+ #clock: () => number
27
+
28
+ constructor(opts: PostgresSessionStoreOptions) {
29
+ this.#exec = opts.exec
30
+ this.#clock = opts.clock ?? (() => Date.now())
31
+ }
32
+
33
+ async saveFlow(
34
+ flowId: string,
35
+ payload: FlowRecord,
36
+ ttl: number,
37
+ ): Promise<Result<void>> {
38
+ if (ttl <= 0) {
39
+ return err(
40
+ authError.internalError(`saveFlow: ttl must be positive, got ${ttl}`),
41
+ )
42
+ }
43
+ const expiresAt = this.#clock() + ttl
44
+ try {
45
+ await this.#exec.query(
46
+ `INSERT INTO openauth_flows (flow_id, payload, expires_at)
47
+ VALUES ($1, $2::jsonb, $3)`,
48
+ [flowId, JSON.stringify(payload), expiresAt],
49
+ )
50
+ } catch (e) {
51
+ return err(authError.internalError("saveFlow: insert failed", e))
52
+ }
53
+ return ok(undefined)
54
+ }
55
+
56
+ async updateFlowMethodState(
57
+ flowId: string,
58
+ methodState: unknown,
59
+ ): Promise<Result<void>> {
60
+ const now = this.#clock()
61
+ let row: { exists: boolean } | undefined
62
+ try {
63
+ // jsonb_set patches the nested key without a read-modify-write race.
64
+ const result = await this.#exec.query<{ exists: boolean }>(
65
+ `UPDATE openauth_flows
66
+ SET payload = jsonb_set(payload, '{methodState}', $1::jsonb, true)
67
+ WHERE flow_id = $2 AND expires_at > $3
68
+ RETURNING true AS exists`,
69
+ [JSON.stringify(methodState), flowId, now],
70
+ )
71
+ row = result.rows[0]
72
+ } catch (e) {
73
+ return err(
74
+ authError.internalError("updateFlowMethodState: update failed", e),
75
+ )
76
+ }
77
+ if (!row) {
78
+ return err(authError.unknownState(`flow "${flowId}" unknown or expired`))
79
+ }
80
+ return ok(undefined)
81
+ }
82
+
83
+ async readFlow(flowId: string): Promise<Result<FlowRecord>> {
84
+ let row: { payload: unknown; expires_at: string | number } | undefined
85
+ try {
86
+ const result = await this.#exec.query<{
87
+ payload: unknown
88
+ expires_at: string | number
89
+ }>(`SELECT payload, expires_at FROM openauth_flows WHERE flow_id = $1`, [
90
+ flowId,
91
+ ])
92
+ row = result.rows[0]
93
+ } catch (e) {
94
+ return err(authError.internalError("readFlow: query failed", e))
95
+ }
96
+ if (!row) {
97
+ return err(authError.unknownState(`flow "${flowId}" unknown`))
98
+ }
99
+ if (this.#clock() >= Number(row.expires_at)) {
100
+ // Lazy GC — best-effort delete, don't fail the read if the delete races.
101
+ try {
102
+ await this.#exec.query(
103
+ `DELETE FROM openauth_flows WHERE flow_id = $1`,
104
+ [flowId],
105
+ )
106
+ } catch {}
107
+ return err(authError.unknownState(`flow "${flowId}" expired`))
108
+ }
109
+ return ok(parseFlowRecord(row.payload))
110
+ }
111
+
112
+ async consumeFlow(flowId: string): Promise<Result<FlowRecord>> {
113
+ let row: { payload: unknown; expires_at: string | number } | undefined
114
+ try {
115
+ // Atomic delete-on-read — single-winner under concurrent presentations.
116
+ const result = await this.#exec.query<{
117
+ payload: unknown
118
+ expires_at: string | number
119
+ }>(
120
+ `DELETE FROM openauth_flows
121
+ WHERE flow_id = $1
122
+ RETURNING payload, expires_at`,
123
+ [flowId],
124
+ )
125
+ row = result.rows[0]
126
+ } catch (e) {
127
+ return err(authError.internalError("consumeFlow: query failed", e))
128
+ }
129
+ if (!row) {
130
+ return err(
131
+ authError.unknownState(`flow "${flowId}" unknown or already consumed`),
132
+ )
133
+ }
134
+ if (this.#clock() >= Number(row.expires_at)) {
135
+ return err(authError.unknownState(`flow "${flowId}" expired`))
136
+ }
137
+ return ok(parseFlowRecord(row.payload))
138
+ }
139
+
140
+ async createSession(
141
+ sessionId: string,
142
+ payload: SessionRecord,
143
+ ttl: number,
144
+ ): Promise<Result<void>> {
145
+ if (ttl <= 0) {
146
+ return err(
147
+ authError.internalError(
148
+ `createSession: ttl must be positive, got ${ttl}`,
149
+ ),
150
+ )
151
+ }
152
+ const expiresAt = this.#clock() + ttl
153
+ try {
154
+ await this.#exec.query(
155
+ `INSERT INTO openauth_sessions (session_id, payload, expires_at)
156
+ VALUES ($1, $2::jsonb, $3)
157
+ ON CONFLICT (session_id) DO UPDATE SET payload = EXCLUDED.payload, expires_at = EXCLUDED.expires_at`,
158
+ [sessionId, JSON.stringify(payload), expiresAt],
159
+ )
160
+ } catch (e) {
161
+ return err(authError.internalError("createSession: insert failed", e))
162
+ }
163
+ return ok(undefined)
164
+ }
165
+
166
+ async readSession(sessionId: string): Promise<Result<SessionRecord>> {
167
+ let row: { payload: unknown; expires_at: string | number } | undefined
168
+ try {
169
+ const result = await this.#exec.query<{
170
+ payload: unknown
171
+ expires_at: string | number
172
+ }>(
173
+ `SELECT payload, expires_at FROM openauth_sessions WHERE session_id = $1`,
174
+ [sessionId],
175
+ )
176
+ row = result.rows[0]
177
+ } catch (e) {
178
+ return err(authError.internalError("readSession: query failed", e))
179
+ }
180
+ if (!row) {
181
+ return err(authError.invalidRequest(`session "${sessionId}" unknown`))
182
+ }
183
+ if (this.#clock() >= Number(row.expires_at)) {
184
+ try {
185
+ await this.#exec.query(
186
+ `DELETE FROM openauth_sessions WHERE session_id = $1`,
187
+ [sessionId],
188
+ )
189
+ } catch {}
190
+ return err(authError.invalidRequest(`session "${sessionId}" expired`))
191
+ }
192
+ return ok(parseSession(row.payload))
193
+ }
194
+
195
+ async revokeSession(sessionId: string): Promise<Result<void>> {
196
+ try {
197
+ await this.#exec.query(
198
+ `DELETE FROM openauth_sessions WHERE session_id = $1`,
199
+ [sessionId],
200
+ )
201
+ } catch (e) {
202
+ return err(authError.internalError("revokeSession: delete failed", e))
203
+ }
204
+ return ok(undefined)
205
+ }
206
+ }
207
+
208
+ function parseFlowRecord(raw: unknown): FlowRecord {
209
+ if (typeof raw === "string") return JSON.parse(raw) as FlowRecord
210
+ return raw as FlowRecord
211
+ }
212
+
213
+ function parseSession(raw: unknown): SessionRecord {
214
+ if (typeof raw === "string") return JSON.parse(raw) as SessionRecord
215
+ return raw as SessionRecord
216
+ }
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Postgres `TokenStore`.
3
+ *
4
+ * - `consumeCode` is an atomic `DELETE … RETURNING` so concurrent
5
+ * presentations of the same code resolve to exactly one winner. The
6
+ * ciphertext blob is stored verbatim — `domain/authorize.ts` encrypts
7
+ * payloads before they reach the adapter (M1), and `domain/token.ts`
8
+ * decrypts after consume. The DB never sees plaintext.
9
+ * - `consumeRefresh` does an atomic `UPDATE … WHERE consumed_at IS NULL
10
+ * RETURNING payload` so a refresh chain has a single live winner per
11
+ * generation. Reuse-detection within the configurable window auto-revokes
12
+ * the family.
13
+ *
14
+ * On reuse-detection the adapter returns `invalid_grant` and populates
15
+ * the structured `reuseSignal` carrier on the error (family / tenantId /
16
+ * subjectId), per the `TokenStore` port contract. The domain's audit
17
+ * emission consumes the typed signal directly — no string parsing.
18
+ */
19
+ import { AUTH_CODE_TTL_MS } from "../../domain/authorize"
20
+ import type { KeyStore } from "../../ports/key-store"
21
+ import type { TokenStore } from "../../ports/token-store"
22
+ import { authError } from "../../types/error"
23
+ import type { Result } from "../../types/result"
24
+ import { err, ok } from "../../types/result"
25
+ import type { TenantId } from "../../types/tenant"
26
+ import type { RefreshTokenPayload } from "../../types/token"
27
+
28
+ import type { PostgresExecutor } from "./executor"
29
+
30
+ export type PostgresTokenStoreOptions = {
31
+ exec: PostgresExecutor
32
+ /**
33
+ * Optional — retained for API stability after M1 moved code-payload
34
+ * encryption to the domain layer. The adapter no longer touches it.
35
+ */
36
+ keyStore?: KeyStore
37
+ /** Injectable clock — defaults to `Date.now`. Tests advance it. */
38
+ clock?: () => number
39
+ }
40
+
41
+ export class PostgresTokenStore implements TokenStore {
42
+ #exec: PostgresExecutor
43
+ #clock: () => number
44
+
45
+ constructor(opts: PostgresTokenStoreOptions) {
46
+ this.#exec = opts.exec
47
+ this.#clock = opts.clock ?? (() => Date.now())
48
+ }
49
+
50
+ async saveCode(
51
+ code: string,
52
+ ciphertext: string,
53
+ ttl: number,
54
+ ): Promise<Result<void>> {
55
+ if (ttl <= 0 || ttl > AUTH_CODE_TTL_MS) {
56
+ return err(
57
+ authError.internalError(
58
+ `saveCode: ttl ${ttl} outside (0, ${AUTH_CODE_TTL_MS}] (auth-code TTL is fixed at 60s by OAuth 2.1 BCP)`,
59
+ ),
60
+ )
61
+ }
62
+ const expiresAt = this.#clock() + ttl
63
+ try {
64
+ await this.#exec.query(
65
+ `INSERT INTO openauth_codes (code, ciphertext, expires_at) VALUES ($1, $2, $3)`,
66
+ [code, ciphertext, expiresAt],
67
+ )
68
+ } catch (e) {
69
+ return err(authError.internalError("saveCode: insert failed", e))
70
+ }
71
+ return ok(undefined)
72
+ }
73
+
74
+ async consumeCode(code: string): Promise<Result<string>> {
75
+ let row: { ciphertext: string; expires_at: string | number } | undefined
76
+ try {
77
+ const result = await this.#exec.query<{
78
+ ciphertext: string
79
+ expires_at: string | number
80
+ }>(
81
+ `DELETE FROM openauth_codes WHERE code = $1 RETURNING ciphertext, expires_at`,
82
+ [code],
83
+ )
84
+ row = result.rows[0]
85
+ } catch (e) {
86
+ return err(authError.internalError("consumeCode: query failed", e))
87
+ }
88
+ if (!row) {
89
+ return err(
90
+ authError.invalidGrant("auth code unknown or already consumed"),
91
+ )
92
+ }
93
+ if (this.#clock() >= Number(row.expires_at)) {
94
+ return err(authError.invalidGrant("auth code expired"))
95
+ }
96
+ return ok(row.ciphertext)
97
+ }
98
+
99
+ async saveRefresh(
100
+ refresh: string,
101
+ payload: RefreshTokenPayload,
102
+ ): Promise<Result<void>> {
103
+ try {
104
+ await this.#exec.query(
105
+ `INSERT INTO openauth_refresh_tokens
106
+ (token, tenant_id, client_id, subject_id, family, expires_at, payload)
107
+ VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb)`,
108
+ [
109
+ refresh,
110
+ payload.tenantId,
111
+ payload.clientId,
112
+ payload.subjectId,
113
+ payload.family,
114
+ payload.expiresAt,
115
+ JSON.stringify(payload),
116
+ ],
117
+ )
118
+ } catch (e) {
119
+ return err(authError.internalError("saveRefresh: insert failed", e))
120
+ }
121
+ return ok(undefined)
122
+ }
123
+
124
+ async consumeRefresh(
125
+ refresh: string,
126
+ options: { reuseWindowMs?: number } = {},
127
+ ): Promise<Result<RefreshTokenPayload>> {
128
+ const reuseWindow = options.reuseWindowMs ?? 60_000
129
+ const now = this.#clock()
130
+ // First try to atomically claim the token — exactly one concurrent caller
131
+ // gets a row back. The UPDATE bounds-checks expiry under the same row
132
+ // lock so an expired token won't be marked consumed under us.
133
+ let claimed: { payload: unknown } | undefined
134
+ try {
135
+ const result = await this.#exec.query<{ payload: unknown }>(
136
+ `UPDATE openauth_refresh_tokens
137
+ SET consumed_at = $1
138
+ WHERE token = $2
139
+ AND consumed_at IS NULL
140
+ AND expires_at > $1
141
+ RETURNING payload`,
142
+ [now, refresh],
143
+ )
144
+ claimed = result.rows[0]
145
+ } catch (e) {
146
+ return err(authError.internalError("consumeRefresh: claim failed", e))
147
+ }
148
+ if (claimed) {
149
+ return ok(parseRefreshPayload(claimed.payload))
150
+ }
151
+ // No row claimed. Find out why — unknown, expired, or already consumed.
152
+ let existing:
153
+ | {
154
+ consumed_at: string | number | null
155
+ expires_at: string | number
156
+ payload: unknown
157
+ }
158
+ | undefined
159
+ try {
160
+ const result = await this.#exec.query<{
161
+ consumed_at: string | number | null
162
+ expires_at: string | number
163
+ payload: unknown
164
+ }>(
165
+ `SELECT consumed_at, expires_at, payload
166
+ FROM openauth_refresh_tokens
167
+ WHERE token = $1`,
168
+ [refresh],
169
+ )
170
+ existing = result.rows[0]
171
+ } catch (e) {
172
+ return err(authError.internalError("consumeRefresh: lookup failed", e))
173
+ }
174
+ if (!existing) {
175
+ return err(authError.invalidGrant("refresh token unknown"))
176
+ }
177
+ if (existing.consumed_at !== null && existing.consumed_at !== undefined) {
178
+ const consumedAt = Number(existing.consumed_at)
179
+ const withinWindow = now - consumedAt <= reuseWindow
180
+ if (withinWindow) {
181
+ const payload = parseRefreshPayload(existing.payload)
182
+ await this.revokeFamily(payload.family)
183
+ return err(
184
+ authError.invalidGrant(
185
+ `refresh token reuse detected (family=${payload.family})`,
186
+ {
187
+ family: payload.family,
188
+ tenantId: payload.tenantId,
189
+ subjectId: payload.subjectId,
190
+ },
191
+ ),
192
+ )
193
+ }
194
+ return err(authError.invalidGrant("refresh token already consumed"))
195
+ }
196
+ if (now >= Number(existing.expires_at)) {
197
+ return err(authError.invalidGrant("refresh token expired"))
198
+ }
199
+ // Should be unreachable — the UPDATE matched neither, but the row is
200
+ // unconsumed and unexpired. Surface as internal so we notice.
201
+ return err(authError.internalError("consumeRefresh: unexplained miss"))
202
+ }
203
+
204
+ async peekRefresh(refresh: string): Promise<Result<RefreshTokenPayload>> {
205
+ let row: { expires_at: string | number; payload: unknown } | undefined
206
+ try {
207
+ const result = await this.#exec.query<{
208
+ expires_at: string | number
209
+ payload: unknown
210
+ }>(
211
+ `SELECT expires_at, payload
212
+ FROM openauth_refresh_tokens
213
+ WHERE token = $1`,
214
+ [refresh],
215
+ )
216
+ row = result.rows[0]
217
+ } catch (e) {
218
+ return err(authError.internalError("peekRefresh: lookup failed", e))
219
+ }
220
+ if (!row) {
221
+ return err(authError.invalidGrant("refresh token unknown"))
222
+ }
223
+ if (this.#clock() >= Number(row.expires_at)) {
224
+ return err(authError.invalidGrant("refresh token expired"))
225
+ }
226
+ return ok(parseRefreshPayload(row.payload))
227
+ }
228
+
229
+ async revokeFamily(family: string): Promise<Result<void>> {
230
+ try {
231
+ await this.#exec.query(
232
+ `DELETE FROM openauth_refresh_tokens WHERE family = $1`,
233
+ [family],
234
+ )
235
+ } catch (e) {
236
+ return err(authError.internalError("revokeFamily: delete failed", e))
237
+ }
238
+ return ok(undefined)
239
+ }
240
+
241
+ async revokeBySubject(
242
+ tenantId: TenantId,
243
+ subjectId: string,
244
+ ): Promise<Result<void>> {
245
+ try {
246
+ await this.#exec.query(
247
+ `DELETE FROM openauth_refresh_tokens
248
+ WHERE tenant_id = $1 AND subject_id = $2`,
249
+ [tenantId, subjectId],
250
+ )
251
+ } catch (e) {
252
+ return err(authError.internalError("revokeBySubject: delete failed", e))
253
+ }
254
+ return ok(undefined)
255
+ }
256
+ }
257
+
258
+ function parseRefreshPayload(raw: unknown): RefreshTokenPayload {
259
+ // PGlite returns parsed JSON; postgres-js may return a string depending on
260
+ // pool config. Be tolerant of both.
261
+ if (typeof raw === "string") return JSON.parse(raw) as RefreshTokenPayload
262
+ return raw as RefreshTokenPayload
263
+ }