@_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,334 @@
1
+ /**
2
+ * Postgres `KeyStore`.
3
+ *
4
+ * Signing keys are persisted as a pair of JWK blobs (public + private) so
5
+ * the framework can transparently `importJWK(privateKeyRef)` on first use.
6
+ * Encryption keys are stored as raw bytes in a `bytea` column.
7
+ *
8
+ * On first read, if no active signing or encryption key exists the adapter
9
+ * auto-generates one. This keeps the developer experience aligned with the
10
+ * memory adapter (no manual bootstrap step) while still respecting whatever
11
+ * keys an operator may have provisioned out-of-band.
12
+ *
13
+ * **At-rest protection.** Pass `wrapper: { wrap, unwrap }` to encrypt the
14
+ * private JWK and the encryption-key bytes under a host-controlled master
15
+ * key (typically a KMS Encrypt/Decrypt round trip). Without a wrapper the
16
+ * adapter stores private material in plaintext at rest — acceptable for
17
+ * dev / local use, **not** acceptable for production. See `INTEGRATION.md`
18
+ * §4. The `private_jwk_wrapped` / `key_material_wrapped` boolean columns
19
+ * record which representation each row uses, so flipping a wrapper on for
20
+ * an existing deployment is a (forthcoming) re-wrap migration rather than
21
+ * a schema change.
22
+ *
23
+ * Rotation (`rotateSigningKeys` / `rotateEncryptionKeys`) is left as a Phase
24
+ * 8 deliverable — schema columns exist for `status` and `rotated_at`, so the
25
+ * later implementation will be a series of `UPDATE` statements without
26
+ * needing a migration.
27
+ */
28
+ import type { JWK } from "jose"
29
+ import { exportJWK, generateKeyPair, importJWK } from "jose"
30
+
31
+ import {
32
+ base64url,
33
+ generateSymmetricKey,
34
+ randomId,
35
+ utf8,
36
+ } from "../../domain/crypto"
37
+ import type {
38
+ EncryptionKey,
39
+ KeyStore,
40
+ KeyWrapper,
41
+ SigningKey,
42
+ } from "../../ports/key-store"
43
+ import { authError } from "../../types/error"
44
+ import type { Result } from "../../types/result"
45
+ import { err, ok } from "../../types/result"
46
+
47
+ import type { PostgresExecutor } from "./executor"
48
+
49
+ export type PostgresKeyStoreOptions = {
50
+ exec: PostgresExecutor
51
+ clock?: () => number
52
+ signingAlg?: "ES256" | "EdDSA"
53
+ /**
54
+ * Optional envelope that encrypts private JWKs and encryption-key bytes
55
+ * before they leave the process. STRONGLY RECOMMENDED in production.
56
+ * Pair with a cloud KMS or HSM-backed implementation.
57
+ */
58
+ wrapper?: KeyWrapper
59
+ }
60
+
61
+ export class PostgresKeyStore implements KeyStore {
62
+ #exec: PostgresExecutor
63
+ #clock: () => number
64
+ #signingAlg: "ES256" | "EdDSA"
65
+ #wrapper: KeyWrapper | undefined
66
+ // Cache imported private keys so we don't re-import on every sign.
67
+ #privateKeyCache = new Map<string, unknown>()
68
+
69
+ constructor(opts: PostgresKeyStoreOptions) {
70
+ this.#exec = opts.exec
71
+ this.#clock = opts.clock ?? (() => Date.now())
72
+ this.#signingAlg = opts.signingAlg ?? "ES256"
73
+ this.#wrapper = opts.wrapper
74
+ }
75
+
76
+ async currentSigningKey(): Promise<Result<SigningKey>> {
77
+ await this.#ensureSigningKey()
78
+ const rows = await this.#selectSigningRows(`status = 'active'`)
79
+ if (rows.length === 0) {
80
+ return err(
81
+ authError.internalError(
82
+ "no active signing key (should be unreachable)",
83
+ ),
84
+ )
85
+ }
86
+ const key = await this.#hydrateSigningKey(rows[0]!)
87
+ return ok(key)
88
+ }
89
+
90
+ async signingKeys(): Promise<Result<SigningKey[]>> {
91
+ await this.#ensureSigningKey()
92
+ const rows = await this.#selectSigningRows(
93
+ `status IN ('active','next','retired')`,
94
+ )
95
+ const keys = await Promise.all(rows.map((r) => this.#hydrateSigningKey(r)))
96
+ return ok(keys)
97
+ }
98
+
99
+ async currentEncryptionKey(): Promise<Result<EncryptionKey>> {
100
+ await this.#ensureEncryptionKey()
101
+ const rows = await this.#selectEncryptionRows(`status = 'active'`)
102
+ if (rows.length === 0) {
103
+ return err(
104
+ authError.internalError(
105
+ "no active encryption key (should be unreachable)",
106
+ ),
107
+ )
108
+ }
109
+ return ok(await this.#hydrateEncryptionKey(rows[0]!))
110
+ }
111
+
112
+ async getEncryptionKey(kid: string): Promise<Result<EncryptionKey>> {
113
+ let row: EncryptionKeyRow | undefined
114
+ try {
115
+ const result = await this.#exec.query<EncryptionKeyRow>(
116
+ `SELECT kid, alg, key_material, key_material_wrapped, status, created_at, rotated_at
117
+ FROM openauth_encryption_keys WHERE kid = $1`,
118
+ [kid],
119
+ )
120
+ row = result.rows[0]
121
+ } catch (e) {
122
+ return err(authError.internalError("getEncryptionKey: query failed", e))
123
+ }
124
+ if (!row) {
125
+ return err(authError.internalError(`encryption key "${kid}" not found`))
126
+ }
127
+ return ok(await this.#hydrateEncryptionKey(row))
128
+ }
129
+
130
+ // --- bootstrap -------------------------------------------------------
131
+
132
+ async #ensureSigningKey(): Promise<void> {
133
+ const rows = await this.#selectSigningRows(`status = 'active'`)
134
+ if (rows.length > 0) return
135
+ const { publicKey, privateKey } = await generateKeyPair(this.#signingAlg, {
136
+ extractable: true,
137
+ })
138
+ const publicJwk = await exportJWK(publicKey)
139
+ const privateJwk = await exportJWK(privateKey)
140
+ const kid = randomId()
141
+ const { jsonPayload, wrapped } = await this.#encodePrivateJwk(privateJwk)
142
+ await this.#exec.query(
143
+ `INSERT INTO openauth_signing_keys
144
+ (kid, alg, crv, public_jwk, private_jwk, private_jwk_wrapped, status, created_at)
145
+ VALUES ($1, $2, $3, $4::jsonb, $5::jsonb, $6, 'active', $7)
146
+ ON CONFLICT (kid) DO NOTHING`,
147
+ [
148
+ kid,
149
+ this.#signingAlg,
150
+ publicJwk.crv ?? null,
151
+ JSON.stringify(publicJwk),
152
+ jsonPayload,
153
+ wrapped,
154
+ this.#clock(),
155
+ ],
156
+ )
157
+ }
158
+
159
+ async #ensureEncryptionKey(): Promise<void> {
160
+ const rows = await this.#selectEncryptionRows(`status = 'active'`)
161
+ if (rows.length > 0) return
162
+ const kid = randomId()
163
+ const raw = generateSymmetricKey() // 32 bytes
164
+ const stored = this.#wrapper ? await this.#wrapper.wrap(raw) : raw
165
+ await this.#exec.query(
166
+ `INSERT INTO openauth_encryption_keys
167
+ (kid, alg, key_material, key_material_wrapped, status, created_at)
168
+ VALUES ($1, $2, $3, $4, 'active', $5)
169
+ ON CONFLICT (kid) DO NOTHING`,
170
+ [kid, "A256GCM", stored, this.#wrapper !== undefined, this.#clock()],
171
+ )
172
+ }
173
+
174
+ /**
175
+ * Encode a private JWK for `private_jwk jsonb` storage. With a wrapper,
176
+ * the plaintext JWK bytes are encrypted and stored as `{"ct": <base64url>}`
177
+ * — never as a recognizable JWK on disk. Without one, the JWK is stored
178
+ * verbatim.
179
+ */
180
+ async #encodePrivateJwk(
181
+ jwk: JWK,
182
+ ): Promise<{ jsonPayload: string; wrapped: boolean }> {
183
+ if (!this.#wrapper) {
184
+ return { jsonPayload: JSON.stringify(jwk), wrapped: false }
185
+ }
186
+ const ciphertext = await this.#wrapper.wrap(
187
+ utf8.encode(JSON.stringify(jwk)),
188
+ )
189
+ return {
190
+ jsonPayload: JSON.stringify({ ct: base64url.encode(ciphertext) }),
191
+ wrapped: true,
192
+ }
193
+ }
194
+
195
+ async #decodePrivateJwk(raw: unknown, wrapped: boolean): Promise<JWK> {
196
+ const parsed =
197
+ typeof raw === "string"
198
+ ? (JSON.parse(raw) as Record<string, unknown>)
199
+ : (raw as Record<string, unknown>)
200
+ if (!wrapped) return parsed as unknown as JWK
201
+ if (!this.#wrapper) {
202
+ throw new Error(
203
+ "PostgresKeyStore: signing key row is wrapped but no `wrapper` was supplied — refusing to read",
204
+ )
205
+ }
206
+ const ct = typeof parsed.ct === "string" ? parsed.ct : ""
207
+ if (!ct) {
208
+ throw new Error("PostgresKeyStore: wrapped signing key row missing `ct`")
209
+ }
210
+ const plaintext = await this.#wrapper.unwrap(base64url.decode(ct))
211
+ return JSON.parse(utf8.decode(plaintext)) as JWK
212
+ }
213
+
214
+ // --- helpers --------------------------------------------------------
215
+
216
+ async #selectSigningRows(where: string): Promise<SigningKeyRow[]> {
217
+ const result = await this.#exec.query<SigningKeyRow>(
218
+ `SELECT kid, alg, crv, public_jwk, private_jwk, private_jwk_wrapped,
219
+ status, created_at, rotated_at
220
+ FROM openauth_signing_keys WHERE ${where}`,
221
+ )
222
+ return result.rows
223
+ }
224
+
225
+ async #selectEncryptionRows(where: string): Promise<EncryptionKeyRow[]> {
226
+ const result = await this.#exec.query<EncryptionKeyRow>(
227
+ `SELECT kid, alg, key_material, key_material_wrapped, status, created_at, rotated_at
228
+ FROM openauth_encryption_keys WHERE ${where}`,
229
+ )
230
+ return result.rows
231
+ }
232
+
233
+ async #hydrateSigningKey(row: SigningKeyRow): Promise<SigningKey> {
234
+ let imported = this.#privateKeyCache.get(row.kid)
235
+ if (!imported) {
236
+ const privateJwk = await this.#decodePrivateJwk(
237
+ row.private_jwk,
238
+ row.private_jwk_wrapped === true,
239
+ )
240
+ imported = await importJWK(privateJwk, row.alg)
241
+ this.#privateKeyCache.set(row.kid, imported)
242
+ }
243
+ const publicJwk =
244
+ typeof row.public_jwk === "string"
245
+ ? (JSON.parse(row.public_jwk) as Record<string, unknown>)
246
+ : (row.public_jwk as Record<string, unknown>)
247
+ return {
248
+ kid: row.kid,
249
+ alg: row.alg,
250
+ ...(row.crv ? { crv: row.crv } : {}),
251
+ publicJwk,
252
+ privateKeyRef: imported,
253
+ status: row.status as SigningKey["status"],
254
+ createdAt: Number(row.created_at),
255
+ ...(row.rotated_at !== null && row.rotated_at !== undefined
256
+ ? { rotatedAt: Number(row.rotated_at) }
257
+ : {}),
258
+ }
259
+ }
260
+
261
+ async #hydrateEncryptionKey(row: EncryptionKeyRow): Promise<EncryptionKey> {
262
+ const stored = ensureBytes(row.key_material)
263
+ let keyRef = stored
264
+ if (row.key_material_wrapped === true) {
265
+ if (!this.#wrapper) {
266
+ throw new Error(
267
+ "PostgresKeyStore: encryption key row is wrapped but no `wrapper` was supplied — refusing to read",
268
+ )
269
+ }
270
+ keyRef = await this.#wrapper.unwrap(stored)
271
+ }
272
+ return {
273
+ kid: row.kid,
274
+ alg: row.alg,
275
+ keyRef,
276
+ status: row.status as EncryptionKey["status"],
277
+ createdAt: Number(row.created_at),
278
+ ...(row.rotated_at !== null && row.rotated_at !== undefined
279
+ ? { rotatedAt: Number(row.rotated_at) }
280
+ : {}),
281
+ }
282
+ }
283
+ }
284
+
285
+ type SigningKeyRow = {
286
+ kid: string
287
+ alg: string
288
+ crv: string | null
289
+ public_jwk: unknown
290
+ private_jwk: unknown
291
+ private_jwk_wrapped: boolean | number | null
292
+ status: string
293
+ created_at: string | number
294
+ rotated_at: string | number | null
295
+ }
296
+
297
+ type EncryptionKeyRow = {
298
+ kid: string
299
+ alg: string
300
+ key_material: Uint8Array | { type: string; data: number[] } | string
301
+ key_material_wrapped: boolean | number | null
302
+ status: string
303
+ created_at: string | number
304
+ rotated_at: string | number | null
305
+ }
306
+
307
+ /**
308
+ * Some drivers return `bytea` columns as `Uint8Array`; some return
309
+ * `Buffer`; some return base64-decoded strings or `{ type: "Buffer", data: [...] }`.
310
+ * Normalize to a plain `Uint8Array` so the encryption path is driver-agnostic.
311
+ */
312
+ function ensureBytes(value: EncryptionKeyRow["key_material"]): Uint8Array {
313
+ if (value instanceof Uint8Array) return value
314
+ if (typeof value === "string") {
315
+ // Best-effort: hex-encoded by postgres-js default; PGlite returns Uint8Array.
316
+ if (/^\\x[0-9a-fA-F]+$/.test(value)) {
317
+ const hex = value.slice(2)
318
+ const out = new Uint8Array(hex.length / 2)
319
+ for (let i = 0; i < out.length; i++) {
320
+ out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16)
321
+ }
322
+ return out
323
+ }
324
+ return new TextEncoder().encode(value)
325
+ }
326
+ if (
327
+ value &&
328
+ typeof value === "object" &&
329
+ "data" in (value as Record<string, unknown>)
330
+ ) {
331
+ return new Uint8Array((value as { data: number[] }).data)
332
+ }
333
+ throw new Error("PostgresKeyStore: unsupported bytea representation")
334
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Postgres `MethodStore`. `(tenant_id, method_id)` composite key, JSONB
3
+ * `config` column for the method-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 { PostgresExecutor } from "./executor"
12
+
13
+ export type PostgresMethodStoreOptions = {
14
+ exec: PostgresExecutor
15
+ clock?: () => number
16
+ }
17
+
18
+ export class PostgresMethodStore implements MethodStore {
19
+ #exec: PostgresExecutor
20
+ #clock: () => number
21
+
22
+ constructor(opts: PostgresMethodStoreOptions) {
23
+ this.#exec = opts.exec
24
+ this.#clock = opts.clock ?? (() => Date.now())
25
+ }
26
+
27
+ async listMethods(tenantId: TenantId): Promise<Result<MethodConfig[]>> {
28
+ try {
29
+ const result = await this.#exec.query<{ config: unknown }>(
30
+ `SELECT config FROM openauth_methods WHERE tenant_id = $1 ORDER BY method_id`,
31
+ [tenantId],
32
+ )
33
+ const methods = result.rows.map((r) => parseConfig(r.config))
34
+ return ok(methods)
35
+ } catch (e) {
36
+ return err(authError.internalError("listMethods: query failed", e))
37
+ }
38
+ }
39
+
40
+ async getMethodConfig(
41
+ tenantId: TenantId,
42
+ methodId: string,
43
+ ): Promise<Result<MethodConfig>> {
44
+ let row: { config: unknown } | undefined
45
+ try {
46
+ const result = await this.#exec.query<{ config: unknown }>(
47
+ `SELECT config FROM openauth_methods WHERE tenant_id = $1 AND method_id = $2`,
48
+ [tenantId, methodId],
49
+ )
50
+ row = result.rows[0]
51
+ } catch (e) {
52
+ return err(authError.internalError("getMethodConfig: query failed", e))
53
+ }
54
+ if (!row) {
55
+ return err(
56
+ authError.methodNotFound(
57
+ `method "${methodId}" not found for tenant "${tenantId}"`,
58
+ { methodId },
59
+ ),
60
+ )
61
+ }
62
+ return ok(parseConfig(row.config))
63
+ }
64
+
65
+ async putMethodConfig(
66
+ tenantId: TenantId,
67
+ method: MethodConfig,
68
+ ): Promise<Result<void>> {
69
+ try {
70
+ await this.#exec.query(
71
+ `INSERT INTO openauth_methods (tenant_id, method_id, config, updated_at)
72
+ VALUES ($1, $2, $3::jsonb, $4)
73
+ ON CONFLICT (tenant_id, method_id) DO UPDATE
74
+ SET config = EXCLUDED.config, updated_at = EXCLUDED.updated_at`,
75
+ [tenantId, method.id, JSON.stringify(method), this.#clock()],
76
+ )
77
+ } catch (e) {
78
+ return err(authError.internalError("putMethodConfig: insert failed", e))
79
+ }
80
+ return ok(undefined)
81
+ }
82
+
83
+ async deleteMethodConfig(
84
+ tenantId: TenantId,
85
+ methodId: string,
86
+ ): Promise<Result<void>> {
87
+ try {
88
+ await this.#exec.query(
89
+ `DELETE FROM openauth_methods WHERE tenant_id = $1 AND method_id = $2`,
90
+ [tenantId, methodId],
91
+ )
92
+ } catch (e) {
93
+ return err(
94
+ authError.internalError("deleteMethodConfig: delete failed", e),
95
+ )
96
+ }
97
+ return ok(undefined)
98
+ }
99
+ }
100
+
101
+ function parseConfig(raw: unknown): MethodConfig {
102
+ if (typeof raw === "string") return JSON.parse(raw) as MethodConfig
103
+ return raw as MethodConfig
104
+ }
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Postgres schema for the IdP adapters. One migration; future schema changes
3
+ * append new migrations and a small migrate-from-version routine.
4
+ *
5
+ * Tables are prefixed `openauth_` so the IdP can share a database with the
6
+ * application that consumes it. The schema is intentionally narrow — JSONB
7
+ * blobs carry the bulk of the data (auth-code ciphertext, refresh payload,
8
+ * tenant config) so that adding fields in later phases is non-breaking.
9
+ *
10
+ * Timestamps are `bigint` (epoch ms) rather than `timestamptz` so that the
11
+ * adapter's injectable clock works seamlessly in tests and so that
12
+ * comparisons are simple integer math.
13
+ */
14
+ import type { PostgresExecutor } from "./executor"
15
+
16
+ export const INITIAL_SCHEMA_SQL = `
17
+ CREATE TABLE IF NOT EXISTS openauth_tenants (
18
+ id text PRIMARY KEY,
19
+ config jsonb NOT NULL,
20
+ updated_at bigint NOT NULL
21
+ );
22
+
23
+ CREATE TABLE IF NOT EXISTS openauth_methods (
24
+ tenant_id text NOT NULL,
25
+ method_id text NOT NULL,
26
+ config jsonb NOT NULL,
27
+ updated_at bigint NOT NULL,
28
+ PRIMARY KEY (tenant_id, method_id)
29
+ );
30
+
31
+ CREATE TABLE IF NOT EXISTS openauth_signing_keys (
32
+ kid text PRIMARY KEY,
33
+ alg text NOT NULL,
34
+ crv text,
35
+ public_jwk jsonb NOT NULL,
36
+ private_jwk jsonb NOT NULL,
37
+ private_jwk_wrapped boolean NOT NULL DEFAULT false,
38
+ status text NOT NULL,
39
+ created_at bigint NOT NULL,
40
+ rotated_at bigint
41
+ );
42
+
43
+ ALTER TABLE openauth_signing_keys
44
+ ADD COLUMN IF NOT EXISTS private_jwk_wrapped boolean NOT NULL DEFAULT false;
45
+
46
+ CREATE TABLE IF NOT EXISTS openauth_encryption_keys (
47
+ kid text PRIMARY KEY,
48
+ alg text NOT NULL,
49
+ key_material bytea NOT NULL,
50
+ key_material_wrapped boolean NOT NULL DEFAULT false,
51
+ status text NOT NULL,
52
+ created_at bigint NOT NULL,
53
+ rotated_at bigint
54
+ );
55
+
56
+ ALTER TABLE openauth_encryption_keys
57
+ ADD COLUMN IF NOT EXISTS key_material_wrapped boolean NOT NULL DEFAULT false;
58
+
59
+ CREATE TABLE IF NOT EXISTS openauth_codes (
60
+ code text PRIMARY KEY,
61
+ ciphertext text NOT NULL,
62
+ expires_at bigint NOT NULL
63
+ );
64
+
65
+ CREATE TABLE IF NOT EXISTS openauth_refresh_tokens (
66
+ token text PRIMARY KEY,
67
+ tenant_id text NOT NULL,
68
+ client_id text NOT NULL,
69
+ subject_id text NOT NULL,
70
+ family text NOT NULL,
71
+ expires_at bigint NOT NULL,
72
+ consumed_at bigint,
73
+ payload jsonb NOT NULL
74
+ );
75
+ CREATE INDEX IF NOT EXISTS openauth_refresh_family_idx
76
+ ON openauth_refresh_tokens (family);
77
+ CREATE INDEX IF NOT EXISTS openauth_refresh_subject_idx
78
+ ON openauth_refresh_tokens (tenant_id, subject_id);
79
+
80
+ CREATE TABLE IF NOT EXISTS openauth_flows (
81
+ flow_id text PRIMARY KEY,
82
+ payload jsonb NOT NULL,
83
+ expires_at bigint NOT NULL
84
+ );
85
+
86
+ CREATE TABLE IF NOT EXISTS openauth_sessions (
87
+ session_id text PRIMARY KEY,
88
+ payload jsonb NOT NULL,
89
+ expires_at bigint NOT NULL
90
+ );
91
+
92
+ CREATE TABLE IF NOT EXISTS openauth_audit_events (
93
+ id bigserial PRIMARY KEY,
94
+ ts bigint NOT NULL,
95
+ kind text NOT NULL,
96
+ payload jsonb NOT NULL
97
+ );
98
+ CREATE INDEX IF NOT EXISTS openauth_audit_kind_idx
99
+ ON openauth_audit_events (kind);
100
+ CREATE INDEX IF NOT EXISTS openauth_audit_ts_idx
101
+ ON openauth_audit_events (ts);
102
+
103
+ CREATE TABLE IF NOT EXISTS openauth_passkey_credentials (
104
+ tenant_id text NOT NULL,
105
+ credential_id text NOT NULL,
106
+ user_id text NOT NULL,
107
+ public_key text NOT NULL,
108
+ counter bigint NOT NULL DEFAULT 0,
109
+ transports jsonb,
110
+ created_at bigint NOT NULL,
111
+ PRIMARY KEY (tenant_id, credential_id)
112
+ );
113
+ CREATE INDEX IF NOT EXISTS openauth_passkey_user_idx
114
+ ON openauth_passkey_credentials (tenant_id, user_id);
115
+ `
116
+
117
+ /**
118
+ * Apply the initial schema. Idempotent — uses `CREATE TABLE IF NOT EXISTS`.
119
+ * Deployments using a real migration tool can apply the SQL above directly
120
+ * and skip this helper.
121
+ */
122
+ export async function migrate(exec: PostgresExecutor): Promise<void> {
123
+ // Some drivers reject a single multi-statement string; PGlite accepts it.
124
+ // Split on the blank line separator + semicolon to handle either case.
125
+ const statements = INITIAL_SCHEMA_SQL.split(/;\s*\n/).filter(
126
+ (s) => s.trim().length > 0,
127
+ )
128
+ for (const stmt of statements) {
129
+ await exec.query(stmt + ";")
130
+ }
131
+ }