@_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,248 @@
1
+ /**
2
+ * DynamoDB `TokenStore`. Single-table design (`pk` / `sk` primary key,
3
+ * `family-index` and `subject-index` GSIs).
4
+ *
5
+ * Per `ports/CONSISTENCY.md`:
6
+ * - All `get`s use `consistentRead: true` — the default eventual-read
7
+ * would violate the auth-code / refresh-token contracts.
8
+ * - All `delete`s use `ReturnValues=ALL_OLD` so atomic delete-on-read is
9
+ * a single round trip.
10
+ * - `consumeRefresh` uses a conditional `UpdateItem` with
11
+ * `attribute_not_exists(consumed_at)` so concurrent presentations
12
+ * resolve to one winner.
13
+ *
14
+ * Layout:
15
+ * - `pk="code"`, `sk=<code>` — auth-code ciphertext blob (the
16
+ * domain encrypts before saveCode; the adapter stores verbatim).
17
+ * - `pk="refresh"`, `sk=<token>` — refresh token + JSON payload.
18
+ * GSI `family-index`: hash = `family`
19
+ * GSI `subject-index`: hash = `subject_key` (`<tenant>#<subject>`)
20
+ */
21
+ import { AUTH_CODE_TTL_MS } from "../../domain/authorize"
22
+ import type { KeyStore } from "../../ports/key-store"
23
+ import type { TokenStore } from "../../ports/token-store"
24
+ import { authError } from "../../types/error"
25
+ import type { Result } from "../../types/result"
26
+ import { err, ok } from "../../types/result"
27
+ import type { TenantId } from "../../types/tenant"
28
+ import type { RefreshTokenPayload } from "../../types/token"
29
+
30
+ import type { DynamoExecutor } from "./client"
31
+
32
+ export type DynamoTokenStoreOptions = {
33
+ exec: DynamoExecutor
34
+ /**
35
+ * Optional — retained for API stability after M1 moved code-payload
36
+ * encryption to the domain layer. The adapter no longer touches it.
37
+ */
38
+ keyStore?: KeyStore
39
+ clock?: () => number
40
+ }
41
+
42
+ export class DynamoTokenStore implements TokenStore {
43
+ #exec: DynamoExecutor
44
+ #clock: () => number
45
+
46
+ constructor(opts: DynamoTokenStoreOptions) {
47
+ this.#exec = opts.exec
48
+ this.#clock = opts.clock ?? (() => Date.now())
49
+ }
50
+
51
+ async saveCode(
52
+ code: string,
53
+ ciphertext: string,
54
+ ttl: number,
55
+ ): Promise<Result<void>> {
56
+ if (ttl <= 0 || ttl > AUTH_CODE_TTL_MS) {
57
+ return err(
58
+ authError.internalError(
59
+ `saveCode: ttl ${ttl} outside (0, ${AUTH_CODE_TTL_MS}] (auth-code TTL is fixed at 60s by OAuth 2.1 BCP)`,
60
+ ),
61
+ )
62
+ }
63
+ const expiresAtMs = this.#clock() + ttl
64
+ try {
65
+ await this.#exec.put({
66
+ item: {
67
+ pk: "code",
68
+ sk: code,
69
+ ciphertext,
70
+ expires_at: expiresAtMs,
71
+ // DynamoDB native TTL is in seconds, named conventionally `ttl`.
72
+ // The adapter writes both so operators can enable TTL on the table.
73
+ ttl: Math.floor(expiresAtMs / 1000),
74
+ },
75
+ })
76
+ } catch (e) {
77
+ return err(authError.internalError("saveCode: put failed", e))
78
+ }
79
+ return ok(undefined)
80
+ }
81
+
82
+ async consumeCode(code: string): Promise<Result<string>> {
83
+ let row: Record<string, unknown> | undefined
84
+ try {
85
+ row = await this.#exec.delete({ key: { pk: "code", sk: code } })
86
+ } catch (e) {
87
+ return err(authError.internalError("consumeCode: delete failed", e))
88
+ }
89
+ if (!row) {
90
+ return err(
91
+ authError.invalidGrant("auth code unknown or already consumed"),
92
+ )
93
+ }
94
+ if (this.#clock() >= Number(row.expires_at)) {
95
+ return err(authError.invalidGrant("auth code expired"))
96
+ }
97
+ return ok(String(row.ciphertext))
98
+ }
99
+
100
+ async saveRefresh(
101
+ refresh: string,
102
+ payload: RefreshTokenPayload,
103
+ ): Promise<Result<void>> {
104
+ try {
105
+ await this.#exec.put({
106
+ item: {
107
+ pk: "refresh",
108
+ sk: refresh,
109
+ payload: JSON.stringify(payload),
110
+ family: payload.family,
111
+ subject_key: `${payload.tenantId}#${payload.subjectId}`,
112
+ tenant_id: payload.tenantId,
113
+ subject_id: payload.subjectId,
114
+ expires_at: payload.expiresAt,
115
+ ttl: Math.floor(payload.expiresAt / 1000),
116
+ },
117
+ })
118
+ } catch (e) {
119
+ return err(authError.internalError("saveRefresh: put failed", e))
120
+ }
121
+ return ok(undefined)
122
+ }
123
+
124
+ async consumeRefresh(
125
+ refresh: string,
126
+ options: { reuseWindowMs?: number } = {},
127
+ ): Promise<Result<RefreshTokenPayload>> {
128
+ const reuseWindow = options.reuseWindowMs ?? 60_000
129
+ const now = this.#clock()
130
+ let claimed: Record<string, unknown> | null
131
+ try {
132
+ claimed = await this.#exec.consumeRefresh({
133
+ key: { pk: "refresh", sk: refresh },
134
+ now,
135
+ })
136
+ } catch (e) {
137
+ return err(authError.internalError("consumeRefresh: claim failed", e))
138
+ }
139
+ if (claimed) {
140
+ return ok(parseRefresh(claimed.payload))
141
+ }
142
+ // No claim. Look up to disambiguate unknown vs already-consumed vs expired.
143
+ let existing: Record<string, unknown> | undefined
144
+ try {
145
+ existing = await this.#exec.get({
146
+ key: { pk: "refresh", sk: refresh },
147
+ consistentRead: true,
148
+ })
149
+ } catch (e) {
150
+ return err(authError.internalError("consumeRefresh: lookup failed", e))
151
+ }
152
+ if (!existing) {
153
+ return err(authError.invalidGrant("refresh token unknown"))
154
+ }
155
+ if (existing.consumed_at !== undefined && existing.consumed_at !== null) {
156
+ const consumedAt = Number(existing.consumed_at)
157
+ const withinWindow = now - consumedAt <= reuseWindow
158
+ if (withinWindow) {
159
+ const payload = parseRefresh(existing.payload)
160
+ await this.revokeFamily(payload.family)
161
+ return err(
162
+ authError.invalidGrant(
163
+ `refresh token reuse detected (family=${payload.family})`,
164
+ {
165
+ family: payload.family,
166
+ tenantId: payload.tenantId,
167
+ subjectId: payload.subjectId,
168
+ },
169
+ ),
170
+ )
171
+ }
172
+ return err(authError.invalidGrant("refresh token already consumed"))
173
+ }
174
+ if (now >= Number(existing.expires_at)) {
175
+ return err(authError.invalidGrant("refresh token expired"))
176
+ }
177
+ return err(authError.internalError("consumeRefresh: unexplained miss"))
178
+ }
179
+
180
+ async peekRefresh(refresh: string): Promise<Result<RefreshTokenPayload>> {
181
+ let existing: Record<string, unknown> | undefined
182
+ try {
183
+ existing = await this.#exec.get({
184
+ key: { pk: "refresh", sk: refresh },
185
+ consistentRead: true,
186
+ })
187
+ } catch (e) {
188
+ return err(authError.internalError("peekRefresh: lookup failed", e))
189
+ }
190
+ if (!existing) {
191
+ return err(authError.invalidGrant("refresh token unknown"))
192
+ }
193
+ if (this.#clock() >= Number(existing.expires_at)) {
194
+ return err(authError.invalidGrant("refresh token expired"))
195
+ }
196
+ return ok(parseRefresh(existing.payload))
197
+ }
198
+
199
+ async revokeFamily(family: string): Promise<Result<void>> {
200
+ let items: Record<string, unknown>[]
201
+ try {
202
+ items = await this.#exec.queryByGsi({
203
+ indexName: "family-index",
204
+ hashKey: family,
205
+ })
206
+ } catch (e) {
207
+ return err(authError.internalError("revokeFamily: query failed", e))
208
+ }
209
+ for (const item of items) {
210
+ try {
211
+ await this.#exec.delete({
212
+ key: { pk: String(item.pk), sk: String(item.sk) },
213
+ })
214
+ } catch {
215
+ // Best-effort — a deletion losing a race is acceptable.
216
+ }
217
+ }
218
+ return ok(undefined)
219
+ }
220
+
221
+ async revokeBySubject(
222
+ tenantId: TenantId,
223
+ subjectId: string,
224
+ ): Promise<Result<void>> {
225
+ let items: Record<string, unknown>[]
226
+ try {
227
+ items = await this.#exec.queryByGsi({
228
+ indexName: "subject-index",
229
+ hashKey: `${tenantId}#${subjectId}`,
230
+ })
231
+ } catch (e) {
232
+ return err(authError.internalError("revokeBySubject: query failed", e))
233
+ }
234
+ for (const item of items) {
235
+ try {
236
+ await this.#exec.delete({
237
+ key: { pk: String(item.pk), sk: String(item.sk) },
238
+ })
239
+ } catch {}
240
+ }
241
+ return ok(undefined)
242
+ }
243
+ }
244
+
245
+ function parseRefresh(raw: unknown): RefreshTokenPayload {
246
+ if (typeof raw === "string") return JSON.parse(raw) as RefreshTokenPayload
247
+ return raw as RefreshTokenPayload
248
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * In-memory `KmsBackingStore`. Used by the KMS adapter conformance test and
3
+ * for single-instance dev. Production deployments pass a real backing store
4
+ * (Postgres, DynamoDB, S3-with-versioning, etc.) so KMS-wrapped key
5
+ * envelopes survive process restarts.
6
+ */
7
+ import type {
8
+ KmsBackingStore,
9
+ WrappedEncryptionKey,
10
+ WrappedSigningKey,
11
+ } from "./types"
12
+
13
+ export function inMemoryKmsBackingStore(): KmsBackingStore {
14
+ const signing = new Map<string, WrappedSigningKey>()
15
+ const encryption = new Map<string, WrappedEncryptionKey>()
16
+ return {
17
+ async putSigningKey(row) {
18
+ signing.set(row.kid, row)
19
+ },
20
+ async getSigningKey(kid) {
21
+ return signing.get(kid)
22
+ },
23
+ async listSigningKeys() {
24
+ return Array.from(signing.values())
25
+ },
26
+ async putEncryptionKey(row) {
27
+ encryption.set(row.kid, row)
28
+ },
29
+ async getEncryptionKey(kid) {
30
+ return encryption.get(kid)
31
+ },
32
+ async listEncryptionKeys() {
33
+ return Array.from(encryption.values())
34
+ },
35
+ }
36
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * KMS-backed `KeyStore` adapter set.
3
+ *
4
+ * Envelope encryption: private JWK material is wrapped under an AWS KMS
5
+ * master key and stored in a pluggable backing store (`KmsBackingStore`).
6
+ * KMS Encrypt / Decrypt are the only KMS operations on the hot path; the
7
+ * framework still receives a real `CryptoKey` for JWT signing so no surgery
8
+ * in `domain/jwt.ts` is needed.
9
+ *
10
+ * @example
11
+ * import { KMSClient } from "@aws-sdk/client-kms"
12
+ * import {
13
+ * fromKmsClient,
14
+ * inMemoryKmsBackingStore,
15
+ * KmsKeyStore,
16
+ * } from "@_mustachio/openauth/adapters/kms"
17
+ *
18
+ * const kms = fromKmsClient(
19
+ * new KMSClient({ region: "us-east-1" }),
20
+ * process.env.IDP_KMS_KEY_ARN!,
21
+ * )
22
+ * // For production, swap in a persistent KmsBackingStore (Postgres,
23
+ * // DynamoDB, etc.). The in-memory store is appropriate for single-instance
24
+ * // dev only.
25
+ * const keyStore = new KmsKeyStore({ kms, backing: inMemoryKmsBackingStore() })
26
+ *
27
+ * Operators with strict no-plaintext-cache requirements can disable the
28
+ * unwrapped-key cache via `cacheUnwrappedKeys: false` — every read then
29
+ * round-trips to KMS.
30
+ */
31
+ export { inMemoryKmsBackingStore } from "./in-memory-backing"
32
+ export { KmsKeyStore, type KmsKeyStoreOptions } from "./key-store"
33
+ export { fromKmsClient } from "./sdk"
34
+ export type {
35
+ KmsBackingStore,
36
+ KmsClientLike,
37
+ WrappedEncryptionKey,
38
+ WrappedSigningKey,
39
+ } from "./types"
@@ -0,0 +1,176 @@
1
+ /**
2
+ * KMS-backed `KeyStore`.
3
+ *
4
+ * Envelope encryption: generate a JWK key pair (or AES key) locally, wrap
5
+ * the private material with AWS KMS `Encrypt`, store the ciphertext in the
6
+ * supplied `KmsBackingStore`. On read, unwrap with KMS `Decrypt` and
7
+ * `importJWK` so the framework receives a normal `CryptoKey` for JWT signing
8
+ * — no surgery in `domain/jwt.ts`.
9
+ *
10
+ * Hot-path KMS calls are cached: signing keys are imported once per
11
+ * `kid` and re-used (a `CryptoKey` is safe to share across signs). Encryption
12
+ * keys are cached in plaintext bytes per `kid` so `consumeCode` doesn't make
13
+ * a KMS call per request.
14
+ *
15
+ * Operators with strict no-cache-of-plaintext requirements can disable the
16
+ * cache via `cacheUnwrappedKeys: false` — every read then round-trips to
17
+ * KMS.
18
+ */
19
+ import type { JWK } from "jose"
20
+ import { exportJWK, generateKeyPair, importJWK } from "jose"
21
+
22
+ import { generateSymmetricKey, randomId, utf8 } from "../../domain/crypto"
23
+ import type { EncryptionKey, KeyStore, SigningKey } from "../../ports/key-store"
24
+ import { authError } from "../../types/error"
25
+ import type { Result } from "../../types/result"
26
+ import { err, ok } from "../../types/result"
27
+
28
+ import type {
29
+ KmsBackingStore,
30
+ KmsClientLike,
31
+ WrappedEncryptionKey,
32
+ WrappedSigningKey,
33
+ } from "./types"
34
+
35
+ export type KmsKeyStoreOptions = {
36
+ kms: KmsClientLike
37
+ backing: KmsBackingStore
38
+ clock?: () => number
39
+ signingAlg?: "ES256" | "EdDSA"
40
+ /** Default `true`. Set false for strict no-plaintext-cache deployments. */
41
+ cacheUnwrappedKeys?: boolean
42
+ }
43
+
44
+ export class KmsKeyStore implements KeyStore {
45
+ #kms: KmsClientLike
46
+ #backing: KmsBackingStore
47
+ #clock: () => number
48
+ #signingAlg: "ES256" | "EdDSA"
49
+ #cacheUnwrapped: boolean
50
+ #signingCache = new Map<string, unknown>()
51
+ #encryptionCache = new Map<string, Uint8Array>()
52
+
53
+ constructor(opts: KmsKeyStoreOptions) {
54
+ this.#kms = opts.kms
55
+ this.#backing = opts.backing
56
+ this.#clock = opts.clock ?? (() => Date.now())
57
+ this.#signingAlg = opts.signingAlg ?? "ES256"
58
+ this.#cacheUnwrapped = opts.cacheUnwrappedKeys ?? true
59
+ }
60
+
61
+ async currentSigningKey(): Promise<Result<SigningKey>> {
62
+ await this.#ensureSigningKey()
63
+ const all = await this.#backing.listSigningKeys()
64
+ const active = all.find((k) => k.status === "active")
65
+ if (!active) {
66
+ return err(
67
+ authError.internalError(
68
+ "no active signing key (should be unreachable)",
69
+ ),
70
+ )
71
+ }
72
+ return ok(await this.#hydrateSigning(active))
73
+ }
74
+
75
+ async signingKeys(): Promise<Result<SigningKey[]>> {
76
+ await this.#ensureSigningKey()
77
+ const all = await this.#backing.listSigningKeys()
78
+ const keys = await Promise.all(all.map((row) => this.#hydrateSigning(row)))
79
+ return ok(keys)
80
+ }
81
+
82
+ async currentEncryptionKey(): Promise<Result<EncryptionKey>> {
83
+ await this.#ensureEncryptionKey()
84
+ const all = await this.#backing.listEncryptionKeys()
85
+ const active = all.find((k) => k.status === "active")
86
+ if (!active) {
87
+ return err(
88
+ authError.internalError(
89
+ "no active encryption key (should be unreachable)",
90
+ ),
91
+ )
92
+ }
93
+ return ok(await this.#hydrateEncryption(active))
94
+ }
95
+
96
+ async getEncryptionKey(kid: string): Promise<Result<EncryptionKey>> {
97
+ const row = await this.#backing.getEncryptionKey(kid)
98
+ if (!row) {
99
+ return err(authError.internalError(`encryption key "${kid}" not found`))
100
+ }
101
+ return ok(await this.#hydrateEncryption(row))
102
+ }
103
+
104
+ async #ensureSigningKey(): Promise<void> {
105
+ const all = await this.#backing.listSigningKeys()
106
+ if (all.some((k) => k.status === "active")) return
107
+ const { publicKey, privateKey } = await generateKeyPair(this.#signingAlg, {
108
+ extractable: true,
109
+ })
110
+ const publicJwk = await exportJWK(publicKey)
111
+ const privateJwk = await exportJWK(privateKey)
112
+ const plaintext = utf8.encode(JSON.stringify(privateJwk))
113
+ const wrapped = await this.#kms.encrypt(plaintext)
114
+ const row: WrappedSigningKey = {
115
+ kid: randomId(),
116
+ alg: this.#signingAlg,
117
+ ...(publicJwk.crv ? { crv: publicJwk.crv } : {}),
118
+ publicJwk: publicJwk as unknown as Record<string, unknown>,
119
+ wrappedPrivate: wrapped,
120
+ status: "active",
121
+ createdAt: this.#clock(),
122
+ }
123
+ await this.#backing.putSigningKey(row)
124
+ }
125
+
126
+ async #ensureEncryptionKey(): Promise<void> {
127
+ const all = await this.#backing.listEncryptionKeys()
128
+ if (all.some((k) => k.status === "active")) return
129
+ const raw = generateSymmetricKey()
130
+ const wrapped = await this.#kms.encrypt(raw)
131
+ const row: WrappedEncryptionKey = {
132
+ kid: randomId(),
133
+ alg: "A256GCM",
134
+ wrappedKey: wrapped,
135
+ status: "active",
136
+ createdAt: this.#clock(),
137
+ }
138
+ await this.#backing.putEncryptionKey(row)
139
+ }
140
+
141
+ async #hydrateSigning(row: WrappedSigningKey): Promise<SigningKey> {
142
+ let imported = this.#signingCache.get(row.kid)
143
+ if (!imported) {
144
+ const plaintext = await this.#kms.decrypt(row.wrappedPrivate)
145
+ const jwk = JSON.parse(utf8.decode(plaintext)) as JWK
146
+ imported = await importJWK(jwk, row.alg)
147
+ if (this.#cacheUnwrapped) this.#signingCache.set(row.kid, imported)
148
+ }
149
+ return {
150
+ kid: row.kid,
151
+ alg: row.alg,
152
+ ...(row.crv ? { crv: row.crv } : {}),
153
+ publicJwk: row.publicJwk,
154
+ privateKeyRef: imported,
155
+ status: row.status,
156
+ createdAt: row.createdAt,
157
+ ...(row.rotatedAt !== undefined ? { rotatedAt: row.rotatedAt } : {}),
158
+ }
159
+ }
160
+
161
+ async #hydrateEncryption(row: WrappedEncryptionKey): Promise<EncryptionKey> {
162
+ let bytes = this.#encryptionCache.get(row.kid)
163
+ if (!bytes) {
164
+ bytes = await this.#kms.decrypt(row.wrappedKey)
165
+ if (this.#cacheUnwrapped) this.#encryptionCache.set(row.kid, bytes)
166
+ }
167
+ return {
168
+ kid: row.kid,
169
+ alg: row.alg,
170
+ keyRef: bytes,
171
+ status: row.status,
172
+ createdAt: row.createdAt,
173
+ ...(row.rotatedAt !== undefined ? { rotatedAt: row.rotatedAt } : {}),
174
+ }
175
+ }
176
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * `fromKmsClient` — wires the `KmsClientLike` interface to a real AWS KMS
3
+ * client. The KMS SDK is imported only from this file to keep the rest of
4
+ * the adapter bundle KMS-agnostic.
5
+ *
6
+ * @example
7
+ * import { KMSClient } from "@aws-sdk/client-kms"
8
+ * const kmsClient = new KMSClient({ region: "us-east-1" })
9
+ * const kms = fromKmsClient(kmsClient, process.env.IDP_KMS_KEY_ARN!)
10
+ * const backing = new PostgresKmsBackingStore({ exec })
11
+ * const keyStore = new KmsKeyStore({ kms, backing })
12
+ */
13
+ import type { KMSClient } from "@aws-sdk/client-kms"
14
+ import { DecryptCommand, EncryptCommand } from "@aws-sdk/client-kms"
15
+
16
+ import type { KmsClientLike } from "./types"
17
+
18
+ export function fromKmsClient(client: KMSClient, keyId: string): KmsClientLike {
19
+ return {
20
+ async encrypt(plaintext: Uint8Array): Promise<Uint8Array> {
21
+ const result = await client.send(
22
+ new EncryptCommand({ KeyId: keyId, Plaintext: plaintext }),
23
+ )
24
+ if (!result.CiphertextBlob) {
25
+ throw new Error("KMS Encrypt returned no ciphertext")
26
+ }
27
+ return new Uint8Array(result.CiphertextBlob)
28
+ },
29
+ async decrypt(ciphertext: Uint8Array): Promise<Uint8Array> {
30
+ const result = await client.send(
31
+ new DecryptCommand({ KeyId: keyId, CiphertextBlob: ciphertext }),
32
+ )
33
+ if (!result.Plaintext) {
34
+ throw new Error("KMS Decrypt returned no plaintext")
35
+ }
36
+ return new Uint8Array(result.Plaintext)
37
+ },
38
+ }
39
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * KMS adapter interfaces.
3
+ *
4
+ * The KMS-backed `KeyStore` uses **envelope encryption** for private key
5
+ * material: the JWK private bytes (signing) and the raw AES key bytes
6
+ * (encryption) are wrapped under a KMS master key. The ciphertext blob is
7
+ * stored in a pluggable backing store; KMS Encrypt / Decrypt are the only
8
+ * KMS operations on the hot path.
9
+ *
10
+ * This shape keeps private material out of plaintext at rest while
11
+ * preserving the JWT signing path: the framework still receives a real
12
+ * `CryptoKey` (`importJWK` of the unwrapped JWK) so `domain/jwt.ts` doesn't
13
+ * need to know KMS exists.
14
+ */
15
+
16
+ /** Minimal KMS surface the adapter depends on. */
17
+ export type KmsClientLike = {
18
+ /** Encrypt up to ~4 KB of plaintext under the master key. */
19
+ encrypt(plaintext: Uint8Array): Promise<Uint8Array>
20
+ /** Decrypt a previously-issued ciphertext under the master key. */
21
+ decrypt(ciphertext: Uint8Array): Promise<Uint8Array>
22
+ }
23
+
24
+ /**
25
+ * Persistent storage for KMS-wrapped key envelopes. Adapters provide their
26
+ * own (Postgres, DynamoDB, file), or pass `inMemoryKmsBackingStore()` for
27
+ * tests / single-instance dev.
28
+ *
29
+ * `wrappedPrivate` is the KMS-wrapped private material (JWK bytes for
30
+ * signing keys, raw AES key bytes for encryption keys). `publicJwk` is the
31
+ * public material (never sensitive); it's kept plaintext alongside the
32
+ * ciphertext so JWKS lookups don't need a KMS round trip.
33
+ */
34
+ export type KmsBackingStore = {
35
+ putSigningKey(row: WrappedSigningKey): Promise<void>
36
+ getSigningKey(kid: string): Promise<WrappedSigningKey | undefined>
37
+ listSigningKeys(): Promise<WrappedSigningKey[]>
38
+ putEncryptionKey(row: WrappedEncryptionKey): Promise<void>
39
+ getEncryptionKey(kid: string): Promise<WrappedEncryptionKey | undefined>
40
+ listEncryptionKeys(): Promise<WrappedEncryptionKey[]>
41
+ }
42
+
43
+ export type WrappedSigningKey = {
44
+ kid: string
45
+ alg: string
46
+ crv?: string
47
+ publicJwk: Record<string, unknown>
48
+ wrappedPrivate: Uint8Array
49
+ status: "active" | "next" | "retired"
50
+ createdAt: number
51
+ rotatedAt?: number
52
+ }
53
+
54
+ export type WrappedEncryptionKey = {
55
+ kid: string
56
+ alg: string
57
+ wrappedKey: Uint8Array
58
+ status: "active" | "next" | "retired"
59
+ createdAt: number
60
+ rotatedAt?: number
61
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Cloudflare KV `AuditLog`. Append-only with per-event keys of the shape
3
+ * `audit:<paddedTs>:<rand>` so KV's lexicographic list returns events in
4
+ * insertion order. Suitable for low-volume audit (the IdP) where reads are
5
+ * SIEM-style after-the-fact, not hot-path. High-volume deployments should
6
+ * ship events out-of-band to a real append-log.
7
+ */
8
+ import type { AuditEvent, AuditLog } from "../../ports/audit-log"
9
+
10
+ import type { KVNamespaceLike } from "./types"
11
+
12
+ const PREFIX = "audit:"
13
+
14
+ export type KvAuditLogOptions = {
15
+ kv: KVNamespaceLike
16
+ /** Optional TTL (seconds). 90 days minimum per CONSISTENCY.md SOC 2 baseline. */
17
+ expirationTtl?: number
18
+ }
19
+
20
+ export class KvAuditLog implements AuditLog {
21
+ #kv: KVNamespaceLike
22
+ #ttl: number | undefined
23
+
24
+ constructor(opts: KvAuditLogOptions) {
25
+ this.#kv = opts.kv
26
+ this.#ttl = opts.expirationTtl
27
+ }
28
+
29
+ async log(event: AuditEvent & { timestamp: number }): Promise<void> {
30
+ const padded = String(event.timestamp).padStart(16, "0")
31
+ const suffix = Math.random().toString(36).slice(2, 10)
32
+ try {
33
+ await this.#kv.put(
34
+ `${PREFIX}${padded}:${suffix}`,
35
+ JSON.stringify(event),
36
+ this.#ttl ? { expirationTtl: this.#ttl } : undefined,
37
+ )
38
+ } catch {}
39
+ }
40
+ }