@_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,41 @@
1
+ /**
2
+ * Cloudflare D1 adapter set.
3
+ *
4
+ * Per AD8 + the D1 read-replication caveat in `ports/CONSISTENCY.md`, every
5
+ * operation on the security-critical paths (`TokenStore`, `SessionStore`)
6
+ * wraps its statement in `db.withSession("first-primary")` so reads observe
7
+ * the latest write. Read-eventual paths (`ConfigStore`, `KeyStore.signingKeys`,
8
+ * `MethodStore`, `AuditLog`) use the plain `D1Database` and benefit from
9
+ * replica reads when available.
10
+ *
11
+ * Feature detection — if the `D1Database` runtime predates the Sessions API,
12
+ * the helper degrades to plain `prepare`. This keeps the adapter compatible
13
+ * with older Workers runtimes and test shims (bun:sqlite via the
14
+ * `test/adapters/d1.test.ts` harness) at the cost of relying on
15
+ * single-replica consistency in those environments.
16
+ *
17
+ * @example
18
+ * export default {
19
+ * async fetch(req, env) {
20
+ * const keyStore = new D1KeyStore({ db: env.AUTH })
21
+ * const tokenStore = new D1TokenStore({ db: env.AUTH, keyStore })
22
+ * // ...
23
+ * }
24
+ * }
25
+ */
26
+ export { D1AuditLog, type D1AuditLogOptions } from "./audit-log"
27
+ export { D1ConfigStore, type D1ConfigStoreOptions } from "./config-store"
28
+ export { D1KeyStore, type D1KeyStoreOptions } from "./key-store"
29
+ export { D1MethodStore, type D1MethodStoreOptions } from "./method-store"
30
+ export { D1SessionStore, type D1SessionStoreOptions } from "./session-store"
31
+ export { D1TokenStore, type D1TokenStoreOptions } from "./token-store"
32
+
33
+ export { INITIAL_SCHEMA_SQL, migrate } from "./migrations"
34
+ export { isSessionsCapable, primarySession } from "./session"
35
+ export {
36
+ type AnyD1Database,
37
+ type D1DatabaseSession,
38
+ type D1DatabaseWithSessions,
39
+ type D1SessionBookmark,
40
+ type D1SessionConstraint,
41
+ } from "./types"
@@ -0,0 +1,218 @@
1
+ /**
2
+ * D1 `KeyStore`. JWK material persisted as JSON-in-TEXT; encryption key
3
+ * material as BLOB. Auto-generates a signing + encryption key on first read
4
+ * so deployments don't need a bootstrap step (production users provisioning
5
+ * keys out-of-band see the existing rows and skip auto-gen).
6
+ */
7
+ import type { JWK } from "jose"
8
+ import { exportJWK, generateKeyPair, importJWK } from "jose"
9
+
10
+ import { generateSymmetricKey, randomId } from "../../domain/crypto"
11
+ import type { EncryptionKey, KeyStore, SigningKey } from "../../ports/key-store"
12
+ import { authError } from "../../types/error"
13
+ import type { Result } from "../../types/result"
14
+ import { err, ok } from "../../types/result"
15
+
16
+ import { primarySession } from "./session"
17
+ import type { AnyD1Database } from "./types"
18
+
19
+ export type D1KeyStoreOptions = {
20
+ db: AnyD1Database
21
+ clock?: () => number
22
+ signingAlg?: "ES256" | "EdDSA"
23
+ }
24
+
25
+ export class D1KeyStore implements KeyStore {
26
+ #db: AnyD1Database
27
+ #clock: () => number
28
+ #signingAlg: "ES256" | "EdDSA"
29
+ #privateKeyCache = new Map<string, unknown>()
30
+
31
+ constructor(opts: D1KeyStoreOptions) {
32
+ this.#db = opts.db
33
+ this.#clock = opts.clock ?? (() => Date.now())
34
+ this.#signingAlg = opts.signingAlg ?? "ES256"
35
+ }
36
+
37
+ async currentSigningKey(): Promise<Result<SigningKey>> {
38
+ await this.#ensureSigningKey()
39
+ const row = await primarySession(this.#db)
40
+ .prepare(
41
+ `SELECT kid, alg, crv, public_jwk, private_jwk, status, created_at, rotated_at
42
+ FROM openauth_signing_keys WHERE status = 'active' LIMIT 1`,
43
+ )
44
+ .first<SigningRow>()
45
+ if (!row) {
46
+ return err(
47
+ authError.internalError(
48
+ "no active signing key (should be unreachable)",
49
+ ),
50
+ )
51
+ }
52
+ return ok(await this.#hydrateSigning(row))
53
+ }
54
+
55
+ async signingKeys(): Promise<Result<SigningKey[]>> {
56
+ await this.#ensureSigningKey()
57
+ const result = await primarySession(this.#db)
58
+ .prepare(
59
+ `SELECT kid, alg, crv, public_jwk, private_jwk, status, created_at, rotated_at
60
+ FROM openauth_signing_keys WHERE status IN ('active','next','retired')`,
61
+ )
62
+ .all<SigningRow>()
63
+ const keys = await Promise.all(
64
+ result.results.map((r) => this.#hydrateSigning(r)),
65
+ )
66
+ return ok(keys)
67
+ }
68
+
69
+ async currentEncryptionKey(): Promise<Result<EncryptionKey>> {
70
+ await this.#ensureEncryptionKey()
71
+ const row = await primarySession(this.#db)
72
+ .prepare(
73
+ `SELECT kid, alg, key_material, status, created_at, rotated_at
74
+ FROM openauth_encryption_keys WHERE status = 'active' LIMIT 1`,
75
+ )
76
+ .first<EncryptionRow>()
77
+ if (!row) {
78
+ return err(
79
+ authError.internalError(
80
+ "no active encryption key (should be unreachable)",
81
+ ),
82
+ )
83
+ }
84
+ return ok(this.#hydrateEncryption(row))
85
+ }
86
+
87
+ async getEncryptionKey(kid: string): Promise<Result<EncryptionKey>> {
88
+ const row = await primarySession(this.#db)
89
+ .prepare(
90
+ `SELECT kid, alg, key_material, status, created_at, rotated_at
91
+ FROM openauth_encryption_keys WHERE kid = ?1`,
92
+ )
93
+ .bind(kid)
94
+ .first<EncryptionRow>()
95
+ if (!row) {
96
+ return err(authError.internalError(`encryption key "${kid}" not found`))
97
+ }
98
+ return ok(this.#hydrateEncryption(row))
99
+ }
100
+
101
+ async #ensureSigningKey(): Promise<void> {
102
+ const existing = await primarySession(this.#db)
103
+ .prepare(
104
+ `SELECT 1 AS one FROM openauth_signing_keys WHERE status = 'active' LIMIT 1`,
105
+ )
106
+ .first<{ one: number }>()
107
+ if (existing) return
108
+ const { publicKey, privateKey } = await generateKeyPair(this.#signingAlg, {
109
+ extractable: true,
110
+ })
111
+ const publicJwk = await exportJWK(publicKey)
112
+ const privateJwk = await exportJWK(privateKey)
113
+ const kid = randomId()
114
+ await primarySession(this.#db)
115
+ .prepare(
116
+ `INSERT OR IGNORE INTO openauth_signing_keys
117
+ (kid, alg, crv, public_jwk, private_jwk, status, created_at)
118
+ VALUES (?1, ?2, ?3, ?4, ?5, 'active', ?6)`,
119
+ )
120
+ .bind(
121
+ kid,
122
+ this.#signingAlg,
123
+ publicJwk.crv ?? null,
124
+ JSON.stringify(publicJwk),
125
+ JSON.stringify(privateJwk),
126
+ this.#clock(),
127
+ )
128
+ .run()
129
+ }
130
+
131
+ async #ensureEncryptionKey(): Promise<void> {
132
+ const existing = await primarySession(this.#db)
133
+ .prepare(
134
+ `SELECT 1 AS one FROM openauth_encryption_keys WHERE status = 'active' LIMIT 1`,
135
+ )
136
+ .first<{ one: number }>()
137
+ if (existing) return
138
+ const kid = randomId()
139
+ const keyMaterial = generateSymmetricKey()
140
+ await primarySession(this.#db)
141
+ .prepare(
142
+ `INSERT OR IGNORE INTO openauth_encryption_keys
143
+ (kid, alg, key_material, status, created_at)
144
+ VALUES (?1, ?2, ?3, 'active', ?4)`,
145
+ )
146
+ .bind(kid, "A256GCM", keyMaterial, this.#clock())
147
+ .run()
148
+ }
149
+
150
+ async #hydrateSigning(row: SigningRow): Promise<SigningKey> {
151
+ let imported = this.#privateKeyCache.get(row.kid)
152
+ if (!imported) {
153
+ const privateJwk = JSON.parse(row.private_jwk) as JWK
154
+ imported = await importJWK(privateJwk, row.alg)
155
+ this.#privateKeyCache.set(row.kid, imported)
156
+ }
157
+ return {
158
+ kid: row.kid,
159
+ alg: row.alg,
160
+ ...(row.crv ? { crv: row.crv } : {}),
161
+ publicJwk: JSON.parse(row.public_jwk) as Record<string, unknown>,
162
+ privateKeyRef: imported,
163
+ status: row.status as SigningKey["status"],
164
+ createdAt: Number(row.created_at),
165
+ ...(row.rotated_at !== null && row.rotated_at !== undefined
166
+ ? { rotatedAt: Number(row.rotated_at) }
167
+ : {}),
168
+ }
169
+ }
170
+
171
+ #hydrateEncryption(row: EncryptionRow): EncryptionKey {
172
+ return {
173
+ kid: row.kid,
174
+ alg: row.alg,
175
+ keyRef: ensureBytes(row.key_material),
176
+ status: row.status as EncryptionKey["status"],
177
+ createdAt: Number(row.created_at),
178
+ ...(row.rotated_at !== null && row.rotated_at !== undefined
179
+ ? { rotatedAt: Number(row.rotated_at) }
180
+ : {}),
181
+ }
182
+ }
183
+ }
184
+
185
+ type SigningRow = {
186
+ kid: string
187
+ alg: string
188
+ crv: string | null
189
+ public_jwk: string
190
+ private_jwk: string
191
+ status: string
192
+ created_at: number
193
+ rotated_at: number | null
194
+ }
195
+
196
+ type EncryptionRow = {
197
+ kid: string
198
+ alg: string
199
+ // D1 / bun:sqlite return BLOB columns as ArrayBuffer | Uint8Array depending
200
+ // on the runtime. Accept both.
201
+ key_material: Uint8Array | ArrayBuffer | { type: string; data: number[] }
202
+ status: string
203
+ created_at: number
204
+ rotated_at: number | null
205
+ }
206
+
207
+ function ensureBytes(value: EncryptionRow["key_material"]): Uint8Array {
208
+ if (value instanceof Uint8Array) return value
209
+ if (value instanceof ArrayBuffer) return new Uint8Array(value)
210
+ if (
211
+ value &&
212
+ typeof value === "object" &&
213
+ "data" in (value as Record<string, unknown>)
214
+ ) {
215
+ return new Uint8Array((value as { data: number[] }).data)
216
+ }
217
+ throw new Error("D1KeyStore: unsupported BLOB representation")
218
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * D1 `MethodStore`. `(tenant_id, method_id)` composite key, JSON-as-TEXT
3
+ * config blob.
4
+ */
5
+ import type { MethodStore } from "../../ports/method-store"
6
+ import { authError } from "../../types/error"
7
+ import type { Result } from "../../types/result"
8
+ import { err, ok } from "../../types/result"
9
+ import type { MethodConfig, TenantId } from "../../types/tenant"
10
+
11
+ import type { AnyD1Database } from "./types"
12
+
13
+ export type D1MethodStoreOptions = {
14
+ db: AnyD1Database
15
+ clock?: () => number
16
+ }
17
+
18
+ export class D1MethodStore implements MethodStore {
19
+ #db: AnyD1Database
20
+ #clock: () => number
21
+
22
+ constructor(opts: D1MethodStoreOptions) {
23
+ this.#db = opts.db
24
+ this.#clock = opts.clock ?? (() => Date.now())
25
+ }
26
+
27
+ async listMethods(tenantId: TenantId): Promise<Result<MethodConfig[]>> {
28
+ try {
29
+ const result = await this.#db
30
+ .prepare(
31
+ `SELECT config FROM openauth_methods WHERE tenant_id = ?1 ORDER BY method_id`,
32
+ )
33
+ .bind(tenantId)
34
+ .all<{ config: string }>()
35
+ return ok(result.results.map((r) => JSON.parse(r.config) as MethodConfig))
36
+ } catch (e) {
37
+ return err(authError.internalError("listMethods: query failed", e))
38
+ }
39
+ }
40
+
41
+ async getMethodConfig(
42
+ tenantId: TenantId,
43
+ methodId: string,
44
+ ): Promise<Result<MethodConfig>> {
45
+ let row: { config: string } | null
46
+ try {
47
+ row = await this.#db
48
+ .prepare(
49
+ `SELECT config FROM openauth_methods WHERE tenant_id = ?1 AND method_id = ?2`,
50
+ )
51
+ .bind(tenantId, methodId)
52
+ .first<{ config: string }>()
53
+ } catch (e) {
54
+ return err(authError.internalError("getMethodConfig: query failed", e))
55
+ }
56
+ if (!row) {
57
+ return err(
58
+ authError.methodNotFound(
59
+ `method "${methodId}" not found for tenant "${tenantId}"`,
60
+ { methodId },
61
+ ),
62
+ )
63
+ }
64
+ return ok(JSON.parse(row.config) as MethodConfig)
65
+ }
66
+
67
+ async putMethodConfig(
68
+ tenantId: TenantId,
69
+ method: MethodConfig,
70
+ ): Promise<Result<void>> {
71
+ try {
72
+ await this.#db
73
+ .prepare(
74
+ `INSERT INTO openauth_methods (tenant_id, method_id, config, updated_at) VALUES (?1, ?2, ?3, ?4)
75
+ ON CONFLICT(tenant_id, method_id) DO UPDATE SET config = excluded.config, updated_at = excluded.updated_at`,
76
+ )
77
+ .bind(tenantId, method.id, JSON.stringify(method), this.#clock())
78
+ .run()
79
+ } catch (e) {
80
+ return err(authError.internalError("putMethodConfig: insert failed", e))
81
+ }
82
+ return ok(undefined)
83
+ }
84
+
85
+ async deleteMethodConfig(
86
+ tenantId: TenantId,
87
+ methodId: string,
88
+ ): Promise<Result<void>> {
89
+ try {
90
+ await this.#db
91
+ .prepare(
92
+ `DELETE FROM openauth_methods WHERE tenant_id = ?1 AND method_id = ?2`,
93
+ )
94
+ .bind(tenantId, methodId)
95
+ .run()
96
+ } catch (e) {
97
+ return err(
98
+ authError.internalError("deleteMethodConfig: delete failed", e),
99
+ )
100
+ }
101
+ return ok(undefined)
102
+ }
103
+ }
@@ -0,0 +1,89 @@
1
+ /**
2
+ * D1 / SQLite schema for the IdP adapters. Mirrors the Postgres schema
3
+ * exactly with SQLite-flavored types (TEXT for JSON, BLOB for bytes,
4
+ * INTEGER for timestamps and serials).
5
+ *
6
+ * The auth-code payload is encrypted at rest by the adapter before the
7
+ * ciphertext lands in `openauth_codes.ciphertext` — the DB only ever sees
8
+ * the JWE compact string.
9
+ */
10
+ import type { AnyD1Database } from "./types"
11
+
12
+ export const INITIAL_SCHEMA_SQL = [
13
+ `CREATE TABLE IF NOT EXISTS openauth_tenants (
14
+ id TEXT PRIMARY KEY,
15
+ config TEXT NOT NULL,
16
+ updated_at INTEGER NOT NULL
17
+ )`,
18
+ `CREATE TABLE IF NOT EXISTS openauth_methods (
19
+ tenant_id TEXT NOT NULL,
20
+ method_id TEXT NOT NULL,
21
+ config TEXT NOT NULL,
22
+ updated_at INTEGER NOT NULL,
23
+ PRIMARY KEY (tenant_id, method_id)
24
+ )`,
25
+ `CREATE TABLE IF NOT EXISTS openauth_signing_keys (
26
+ kid TEXT PRIMARY KEY,
27
+ alg TEXT NOT NULL,
28
+ crv TEXT,
29
+ public_jwk TEXT NOT NULL,
30
+ private_jwk TEXT NOT NULL,
31
+ status TEXT NOT NULL,
32
+ created_at INTEGER NOT NULL,
33
+ rotated_at INTEGER
34
+ )`,
35
+ `CREATE TABLE IF NOT EXISTS openauth_encryption_keys (
36
+ kid TEXT PRIMARY KEY,
37
+ alg TEXT NOT NULL,
38
+ key_material BLOB NOT NULL,
39
+ status TEXT NOT NULL,
40
+ created_at INTEGER NOT NULL,
41
+ rotated_at INTEGER
42
+ )`,
43
+ `CREATE TABLE IF NOT EXISTS openauth_codes (
44
+ code TEXT PRIMARY KEY,
45
+ ciphertext TEXT NOT NULL,
46
+ expires_at INTEGER NOT NULL
47
+ )`,
48
+ `CREATE TABLE IF NOT EXISTS openauth_refresh_tokens (
49
+ token TEXT PRIMARY KEY,
50
+ tenant_id TEXT NOT NULL,
51
+ client_id TEXT NOT NULL,
52
+ subject_id TEXT NOT NULL,
53
+ family TEXT NOT NULL,
54
+ expires_at INTEGER NOT NULL,
55
+ consumed_at INTEGER,
56
+ payload TEXT NOT NULL
57
+ )`,
58
+ `CREATE INDEX IF NOT EXISTS openauth_refresh_family_idx ON openauth_refresh_tokens (family)`,
59
+ `CREATE INDEX IF NOT EXISTS openauth_refresh_subject_idx ON openauth_refresh_tokens (tenant_id, subject_id)`,
60
+ `CREATE TABLE IF NOT EXISTS openauth_flows (
61
+ flow_id TEXT PRIMARY KEY,
62
+ payload TEXT NOT NULL,
63
+ expires_at INTEGER NOT NULL
64
+ )`,
65
+ `CREATE TABLE IF NOT EXISTS openauth_sessions (
66
+ session_id TEXT PRIMARY KEY,
67
+ payload TEXT NOT NULL,
68
+ expires_at INTEGER NOT NULL
69
+ )`,
70
+ `CREATE TABLE IF NOT EXISTS openauth_audit_events (
71
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
72
+ ts INTEGER NOT NULL,
73
+ kind TEXT NOT NULL,
74
+ payload TEXT NOT NULL
75
+ )`,
76
+ `CREATE INDEX IF NOT EXISTS openauth_audit_kind_idx ON openauth_audit_events (kind)`,
77
+ `CREATE INDEX IF NOT EXISTS openauth_audit_ts_idx ON openauth_audit_events (ts)`,
78
+ ]
79
+
80
+ /**
81
+ * Apply the initial schema to a D1 database. Idempotent — every statement
82
+ * is `CREATE … IF NOT EXISTS`. Deployments using `wrangler d1 migrations
83
+ * apply` can apply the SQL above directly.
84
+ */
85
+ export async function migrate(db: AnyD1Database): Promise<void> {
86
+ for (const stmt of INITIAL_SCHEMA_SQL) {
87
+ await db.prepare(stmt).run()
88
+ }
89
+ }
@@ -0,0 +1,230 @@
1
+ /**
2
+ * D1 `SessionStore`. Flow records + optional long-lived sessions.
3
+ *
4
+ * `consumeFlow` is `DELETE … RETURNING payload, expires_at` — atomic
5
+ * single-winner. `updateFlowMethodState` re-serializes the entire payload
6
+ * blob (SQLite has no `jsonb_set`); the read-then-write is wrapped inside
7
+ * the same `primarySession` so the bookmark advances atomically.
8
+ */
9
+ import { authError } from "../../types/error"
10
+ import type { FlowRecord } from "../../types/flow"
11
+ import type { SessionRecord, SessionStore } from "../../ports/session-store"
12
+ import type { Result } from "../../types/result"
13
+ import { err, ok } from "../../types/result"
14
+
15
+ import { primarySession } from "./session"
16
+ import type { AnyD1Database } from "./types"
17
+
18
+ export type D1SessionStoreOptions = {
19
+ db: AnyD1Database
20
+ clock?: () => number
21
+ }
22
+
23
+ export class D1SessionStore implements SessionStore {
24
+ #db: AnyD1Database
25
+ #clock: () => number
26
+
27
+ constructor(opts: D1SessionStoreOptions) {
28
+ this.#db = opts.db
29
+ this.#clock = opts.clock ?? (() => Date.now())
30
+ }
31
+
32
+ async saveFlow(
33
+ flowId: string,
34
+ payload: FlowRecord,
35
+ ttl: number,
36
+ ): Promise<Result<void>> {
37
+ if (ttl <= 0) {
38
+ return err(
39
+ authError.internalError(`saveFlow: ttl must be positive, got ${ttl}`),
40
+ )
41
+ }
42
+ const expiresAt = this.#clock() + ttl
43
+ try {
44
+ await primarySession(this.#db)
45
+ .prepare(
46
+ `INSERT INTO openauth_flows (flow_id, payload, expires_at) VALUES (?1, ?2, ?3)`,
47
+ )
48
+ .bind(flowId, JSON.stringify(payload), expiresAt)
49
+ .run()
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
+ const session = primarySession(this.#db)
62
+ let row: { payload: string; expires_at: number } | null
63
+ try {
64
+ row = await session
65
+ .prepare(
66
+ `SELECT payload, expires_at FROM openauth_flows WHERE flow_id = ?1`,
67
+ )
68
+ .bind(flowId)
69
+ .first<{ payload: string; expires_at: number }>()
70
+ } catch (e) {
71
+ return err(
72
+ authError.internalError("updateFlowMethodState: read failed", e),
73
+ )
74
+ }
75
+ if (!row) {
76
+ return err(authError.unknownState(`flow "${flowId}" unknown`))
77
+ }
78
+ if (now >= Number(row.expires_at)) {
79
+ return err(authError.unknownState(`flow "${flowId}" expired`))
80
+ }
81
+ let parsed: FlowRecord
82
+ try {
83
+ parsed = JSON.parse(row.payload) as FlowRecord
84
+ } catch (e) {
85
+ return err(
86
+ authError.internalError("updateFlowMethodState: parse failed", e),
87
+ )
88
+ }
89
+ const next = { ...parsed, methodState }
90
+ try {
91
+ // Conditional write — only update if the row still exists AND has
92
+ // matching expiry. If a concurrent consume snuck in, the WHERE clause
93
+ // misses and we surface `unknown_state`.
94
+ const result = await session
95
+ .prepare(
96
+ `UPDATE openauth_flows SET payload = ?1
97
+ WHERE flow_id = ?2 AND expires_at > ?3
98
+ RETURNING 1 AS hit`,
99
+ )
100
+ .bind(JSON.stringify(next), flowId, now)
101
+ .first<{ hit: number }>()
102
+ if (!result) {
103
+ return err(
104
+ authError.unknownState(`flow "${flowId}" unknown or expired`),
105
+ )
106
+ }
107
+ } catch (e) {
108
+ return err(
109
+ authError.internalError("updateFlowMethodState: update failed", e),
110
+ )
111
+ }
112
+ return ok(undefined)
113
+ }
114
+
115
+ async readFlow(flowId: string): Promise<Result<FlowRecord>> {
116
+ let row: { payload: string; expires_at: number } | null
117
+ try {
118
+ row = await primarySession(this.#db)
119
+ .prepare(
120
+ `SELECT payload, expires_at FROM openauth_flows WHERE flow_id = ?1`,
121
+ )
122
+ .bind(flowId)
123
+ .first<{ payload: string; expires_at: number }>()
124
+ } catch (e) {
125
+ return err(authError.internalError("readFlow: query failed", e))
126
+ }
127
+ if (!row) {
128
+ return err(authError.unknownState(`flow "${flowId}" unknown`))
129
+ }
130
+ if (this.#clock() >= Number(row.expires_at)) {
131
+ try {
132
+ await primarySession(this.#db)
133
+ .prepare(`DELETE FROM openauth_flows WHERE flow_id = ?1`)
134
+ .bind(flowId)
135
+ .run()
136
+ } catch {}
137
+ return err(authError.unknownState(`flow "${flowId}" expired`))
138
+ }
139
+ return ok(JSON.parse(row.payload) as FlowRecord)
140
+ }
141
+
142
+ async consumeFlow(flowId: string): Promise<Result<FlowRecord>> {
143
+ let row: { payload: string; expires_at: number } | null
144
+ try {
145
+ row = await primarySession(this.#db)
146
+ .prepare(
147
+ `DELETE FROM openauth_flows WHERE flow_id = ?1 RETURNING payload, expires_at`,
148
+ )
149
+ .bind(flowId)
150
+ .first<{ payload: string; expires_at: number }>()
151
+ } catch (e) {
152
+ return err(authError.internalError("consumeFlow: query failed", e))
153
+ }
154
+ if (!row) {
155
+ return err(
156
+ authError.unknownState(`flow "${flowId}" unknown or already consumed`),
157
+ )
158
+ }
159
+ if (this.#clock() >= Number(row.expires_at)) {
160
+ return err(authError.unknownState(`flow "${flowId}" expired`))
161
+ }
162
+ return ok(JSON.parse(row.payload) as FlowRecord)
163
+ }
164
+
165
+ async createSession(
166
+ sessionId: string,
167
+ payload: SessionRecord,
168
+ ttl: number,
169
+ ): Promise<Result<void>> {
170
+ if (ttl <= 0) {
171
+ return err(
172
+ authError.internalError(
173
+ `createSession: ttl must be positive, got ${ttl}`,
174
+ ),
175
+ )
176
+ }
177
+ const expiresAt = this.#clock() + ttl
178
+ try {
179
+ await primarySession(this.#db)
180
+ .prepare(
181
+ `INSERT INTO openauth_sessions (session_id, payload, expires_at) VALUES (?1, ?2, ?3)
182
+ ON CONFLICT(session_id) DO UPDATE SET payload = excluded.payload, expires_at = excluded.expires_at`,
183
+ )
184
+ .bind(sessionId, JSON.stringify(payload), expiresAt)
185
+ .run()
186
+ } catch (e) {
187
+ return err(authError.internalError("createSession: insert failed", e))
188
+ }
189
+ return ok(undefined)
190
+ }
191
+
192
+ async readSession(sessionId: string): Promise<Result<SessionRecord>> {
193
+ let row: { payload: string; expires_at: number } | null
194
+ try {
195
+ row = await primarySession(this.#db)
196
+ .prepare(
197
+ `SELECT payload, expires_at FROM openauth_sessions WHERE session_id = ?1`,
198
+ )
199
+ .bind(sessionId)
200
+ .first<{ payload: string; expires_at: number }>()
201
+ } catch (e) {
202
+ return err(authError.internalError("readSession: query failed", e))
203
+ }
204
+ if (!row) {
205
+ return err(authError.invalidRequest(`session "${sessionId}" unknown`))
206
+ }
207
+ if (this.#clock() >= Number(row.expires_at)) {
208
+ try {
209
+ await primarySession(this.#db)
210
+ .prepare(`DELETE FROM openauth_sessions WHERE session_id = ?1`)
211
+ .bind(sessionId)
212
+ .run()
213
+ } catch {}
214
+ return err(authError.invalidRequest(`session "${sessionId}" expired`))
215
+ }
216
+ return ok(JSON.parse(row.payload) as SessionRecord)
217
+ }
218
+
219
+ async revokeSession(sessionId: string): Promise<Result<void>> {
220
+ try {
221
+ await primarySession(this.#db)
222
+ .prepare(`DELETE FROM openauth_sessions WHERE session_id = ?1`)
223
+ .bind(sessionId)
224
+ .run()
225
+ } catch (e) {
226
+ return err(authError.internalError("revokeSession: delete failed", e))
227
+ }
228
+ return ok(undefined)
229
+ }
230
+ }