@_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,37 @@
1
+ /**
2
+ * LinkedIn — OAuth 2.0. Default scopes: `r_liteprofile r_emailaddress`.
3
+ */
4
+ import { z } from "zod"
5
+
6
+ import { buildOauth2Method } from "../oauth2-generic"
7
+ import type { Oauth2Properties, Oauth2State } from "../oauth2-generic"
8
+ import type { AuthMethod, AuthMethodFactory } from "../../types/method"
9
+
10
+ const schema = z.object({
11
+ clientId: z.string(),
12
+ clientSecret: z.string(),
13
+ scopes: z.array(z.string()).optional(),
14
+ })
15
+
16
+ export const linkedinFactory: AuthMethodFactory<
17
+ Oauth2Properties,
18
+ Oauth2State,
19
+ z.infer<typeof schema>
20
+ > = {
21
+ kind: "linkedin",
22
+ configSchema: schema,
23
+ build: async ({
24
+ id,
25
+ kind,
26
+ config,
27
+ }): Promise<AuthMethod<Oauth2Properties, Oauth2State>> =>
28
+ buildOauth2Method({
29
+ id,
30
+ kind,
31
+ authorizationUrl: "https://www.linkedin.com/oauth/v2/authorization",
32
+ tokenUrl: "https://www.linkedin.com/oauth/v2/accessToken",
33
+ clientId: config.clientId,
34
+ clientSecret: config.clientSecret,
35
+ scopes: config.scopes ?? ["r_liteprofile", "r_emailaddress"],
36
+ }),
37
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Microsoft — OIDC, tenant-templated. The `tenant` field is `"common"`,
3
+ * `"organizations"`, `"consumers"`, or a specific Entra tenant id /
4
+ * domain.
5
+ *
6
+ * Discovery is fetched per tenant; the result is cached inside the
7
+ * `MethodCache` so subsequent flows skip the round trip.
8
+ */
9
+ import { z } from "zod"
10
+
11
+ import { buildOidcMethod } from "../oidc-generic"
12
+ import type { Oauth2Properties, Oauth2State } from "../oauth2-generic"
13
+ import type { AuthMethod, AuthMethodFactory } from "../../types/method"
14
+
15
+ const schema = z.object({
16
+ clientId: z.string(),
17
+ clientSecret: z.string(),
18
+ tenant: z.string().optional(),
19
+ scopes: z.array(z.string()).optional(),
20
+ })
21
+
22
+ export const microsoftFactory: AuthMethodFactory<
23
+ Oauth2Properties,
24
+ Oauth2State,
25
+ z.infer<typeof schema>
26
+ > = {
27
+ kind: "microsoft",
28
+ configSchema: schema,
29
+ build: async ({
30
+ id,
31
+ kind,
32
+ config,
33
+ }): Promise<AuthMethod<Oauth2Properties, Oauth2State>> =>
34
+ buildOidcMethod({
35
+ id,
36
+ kind,
37
+ issuer: `https://login.microsoftonline.com/${config.tenant ?? "common"}/v2.0`,
38
+ clientId: config.clientId,
39
+ clientSecret: config.clientSecret,
40
+ scopes: config.scopes ?? ["openid", "email", "profile"],
41
+ }),
42
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Slack — Sign in with Slack (OpenID Connect on Slack's own endpoints).
3
+ * Slack ships an id_token at the token endpoint; we treat it as OIDC.
4
+ *
5
+ * Default scopes: `openid email profile`.
6
+ */
7
+ import { z } from "zod"
8
+
9
+ import { buildOauth2Method } from "../oauth2-generic"
10
+ import type { Oauth2Properties, Oauth2State } from "../oauth2-generic"
11
+ import type { AuthMethod, AuthMethodFactory } from "../../types/method"
12
+
13
+ const schema = z.object({
14
+ clientId: z.string(),
15
+ clientSecret: z.string(),
16
+ scopes: z.array(z.string()).optional(),
17
+ })
18
+
19
+ export const slackFactory: AuthMethodFactory<
20
+ Oauth2Properties,
21
+ Oauth2State,
22
+ z.infer<typeof schema>
23
+ > = {
24
+ kind: "slack",
25
+ configSchema: schema,
26
+ build: async ({
27
+ id,
28
+ kind,
29
+ config,
30
+ }): Promise<AuthMethod<Oauth2Properties, Oauth2State>> =>
31
+ buildOauth2Method({
32
+ id,
33
+ kind,
34
+ authorizationUrl: "https://slack.com/openid/connect/authorize",
35
+ tokenUrl: "https://slack.com/api/openid.connect.token",
36
+ jwksUri: "https://slack.com/openid/connect/keys",
37
+ expectedIssuer: "https://slack.com",
38
+ clientId: config.clientId,
39
+ clientSecret: config.clientSecret,
40
+ scopes: config.scopes ?? ["openid", "email", "profile"],
41
+ }),
42
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Spotify — OAuth 2.0. Default scopes: `user-read-email user-read-private`.
3
+ */
4
+ import { z } from "zod"
5
+
6
+ import { buildOauth2Method } from "../oauth2-generic"
7
+ import type { Oauth2Properties, Oauth2State } from "../oauth2-generic"
8
+ import type { AuthMethod, AuthMethodFactory } from "../../types/method"
9
+
10
+ const schema = z.object({
11
+ clientId: z.string(),
12
+ clientSecret: z.string(),
13
+ scopes: z.array(z.string()).optional(),
14
+ })
15
+
16
+ export const spotifyFactory: AuthMethodFactory<
17
+ Oauth2Properties,
18
+ Oauth2State,
19
+ z.infer<typeof schema>
20
+ > = {
21
+ kind: "spotify",
22
+ configSchema: schema,
23
+ build: async ({
24
+ id,
25
+ kind,
26
+ config,
27
+ }): Promise<AuthMethod<Oauth2Properties, Oauth2State>> =>
28
+ buildOauth2Method({
29
+ id,
30
+ kind,
31
+ authorizationUrl: "https://accounts.spotify.com/authorize",
32
+ tokenUrl: "https://accounts.spotify.com/api/token",
33
+ clientId: config.clientId,
34
+ clientSecret: config.clientSecret,
35
+ scopes: config.scopes ?? ["user-read-email", "user-read-private"],
36
+ }),
37
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Twitch — OAuth 2.0 (Twitch supports OIDC but uses OAuth flows by
3
+ * default). Default scopes: `user:read:email`.
4
+ */
5
+ import { z } from "zod"
6
+
7
+ import { buildOauth2Method } from "../oauth2-generic"
8
+ import type { Oauth2Properties, Oauth2State } from "../oauth2-generic"
9
+ import type { AuthMethod, AuthMethodFactory } from "../../types/method"
10
+
11
+ const schema = z.object({
12
+ clientId: z.string(),
13
+ clientSecret: z.string(),
14
+ scopes: z.array(z.string()).optional(),
15
+ })
16
+
17
+ export const twitchFactory: AuthMethodFactory<
18
+ Oauth2Properties,
19
+ Oauth2State,
20
+ z.infer<typeof schema>
21
+ > = {
22
+ kind: "twitch",
23
+ configSchema: schema,
24
+ build: async ({
25
+ id,
26
+ kind,
27
+ config,
28
+ }): Promise<AuthMethod<Oauth2Properties, Oauth2State>> =>
29
+ buildOauth2Method({
30
+ id,
31
+ kind,
32
+ authorizationUrl: "https://id.twitch.tv/oauth2/authorize",
33
+ tokenUrl: "https://id.twitch.tv/oauth2/token",
34
+ clientId: config.clientId,
35
+ clientSecret: config.clientSecret,
36
+ scopes: config.scopes ?? ["user:read:email"],
37
+ }),
38
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * X (formerly Twitter) — OAuth 2.0 with PKCE. Default scope: `tweet.read users.read`.
3
+ *
4
+ * X requires PKCE on its OAuth 2.0 endpoints; `pkce` is left at the
5
+ * `"S256"` default.
6
+ */
7
+ import { z } from "zod"
8
+
9
+ import { buildOauth2Method } from "../oauth2-generic"
10
+ import type { Oauth2Properties, Oauth2State } from "../oauth2-generic"
11
+ import type { AuthMethod, AuthMethodFactory } from "../../types/method"
12
+
13
+ const schema = z.object({
14
+ clientId: z.string(),
15
+ clientSecret: z.string(),
16
+ scopes: z.array(z.string()).optional(),
17
+ })
18
+
19
+ export const xFactory: AuthMethodFactory<
20
+ Oauth2Properties,
21
+ Oauth2State,
22
+ z.infer<typeof schema>
23
+ > = {
24
+ kind: "x",
25
+ configSchema: schema,
26
+ build: async ({
27
+ id,
28
+ kind,
29
+ config,
30
+ }): Promise<AuthMethod<Oauth2Properties, Oauth2State>> =>
31
+ buildOauth2Method({
32
+ id,
33
+ kind,
34
+ authorizationUrl: "https://twitter.com/i/oauth2/authorize",
35
+ tokenUrl: "https://api.x.com/2/oauth2/token",
36
+ clientId: config.clientId,
37
+ clientSecret: config.clientSecret,
38
+ scopes: config.scopes ?? ["tweet.read", "users.read"],
39
+ }),
40
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Yahoo — OIDC. Default scopes: `openid email profile`.
3
+ */
4
+ import { z } from "zod"
5
+
6
+ import { buildOidcMethod } from "../oidc-generic"
7
+ import type { Oauth2Properties, Oauth2State } from "../oauth2-generic"
8
+ import type { AuthMethod, AuthMethodFactory } from "../../types/method"
9
+
10
+ const schema = z.object({
11
+ clientId: z.string(),
12
+ clientSecret: z.string(),
13
+ scopes: z.array(z.string()).optional(),
14
+ })
15
+
16
+ export const yahooFactory: AuthMethodFactory<
17
+ Oauth2Properties,
18
+ Oauth2State,
19
+ z.infer<typeof schema>
20
+ > = {
21
+ kind: "yahoo",
22
+ configSchema: schema,
23
+ build: async ({
24
+ id,
25
+ kind,
26
+ config,
27
+ }): Promise<AuthMethod<Oauth2Properties, Oauth2State>> =>
28
+ buildOidcMethod({
29
+ id,
30
+ kind,
31
+ issuer: "https://api.login.yahoo.com",
32
+ clientId: config.clientId,
33
+ clientSecret: config.clientSecret,
34
+ scopes: config.scopes ?? ["openid", "email", "profile"],
35
+ }),
36
+ }
package/src/pkce.ts CHANGED
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Client-side PKCE generator — used by `@_mustachio/openauth/client` to
3
+ * produce a verifier + S256 challenge pair before redirecting the user to
4
+ * `/authorize`.
5
+ *
6
+ * S256-only. Per OAuth 2.1 the `plain` method is prohibited; this module
7
+ * does not expose a verifier-comparison helper because IdP-side validation
8
+ * lives in `domain/pkce.ts` and runs against the stored challenge from the
9
+ * auth-code payload — no consumer of this file has a legitimate reason to
10
+ * recompute a challenge.
11
+ */
1
12
  import { base64url } from "jose"
2
13
 
3
14
  function generateVerifier(length: number): string {
@@ -6,35 +17,23 @@ function generateVerifier(length: number): string {
6
17
  return base64url.encode(buffer)
7
18
  }
8
19
 
9
- async function generateChallenge(verifier: string, method: "S256" | "plain") {
10
- if (method === "plain") return verifier
11
- const encoder = new TextEncoder()
12
- const data = encoder.encode(verifier)
20
+ async function s256Challenge(verifier: string): Promise<string> {
21
+ const data = new TextEncoder().encode(verifier)
13
22
  const hash = await crypto.subtle.digest("SHA-256", data)
14
23
  return base64url.encode(new Uint8Array(hash))
15
24
  }
16
25
 
17
- export async function generatePKCE(length: number = 64) {
26
+ export async function generatePKCE(length: number = 64): Promise<{
27
+ verifier: string
28
+ challenge: string
29
+ method: "S256"
30
+ }> {
18
31
  if (length < 43 || length > 128) {
19
32
  throw new Error(
20
33
  "Code verifier length must be between 43 and 128 characters",
21
34
  )
22
35
  }
23
36
  const verifier = generateVerifier(length)
24
- const challenge = await generateChallenge(verifier, "S256")
25
- return {
26
- verifier,
27
- challenge,
28
- method: "S256",
29
- }
30
- }
31
-
32
- export async function validatePKCE(
33
- verifier: string,
34
- challenge: string,
35
- method: "S256" | "plain" = "S256",
36
- ) {
37
- const generatedChallenge = await generateChallenge(verifier, method)
38
- // timing safe equals?
39
- return generatedChallenge === challenge
37
+ const challenge = await s256Challenge(verifier)
38
+ return { verifier, challenge, method: "S256" }
40
39
  }
@@ -0,0 +1,88 @@
1
+ # Port consistency contracts
2
+
3
+ This document is **normative**. Adapter implementations that do not meet
4
+ the per-method consistency requirement below are **not certified for
5
+ production** and must not be wired into a deployed IdP. The phase-1 test
6
+ fixtures and the phase-6 adapter integration suite exist to verify these
7
+ contracts hold against real backends.
8
+
9
+ Storage ports differ in their consistency needs because the security
10
+ properties of the OAuth flows depend on specific atomicity / linearizability
11
+ guarantees at specific points. A blanket "use a strongly consistent KV"
12
+ overspecifies adapters that don't need that on the read-eventual paths
13
+ (tenant config, JWKS); under-specifying any of the strong paths
14
+ (`consumeCode`, `consumeRefresh`, `consumeFlow`) is a critical security bug.
15
+
16
+ ## Per-method consistency contracts
17
+
18
+ | Port | Method | Required | Why |
19
+ | -------------- | ------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
20
+ | `TokenStore` | `saveCode(code, payload, ttl)` | **Strong, atomic.** Payload **encrypted at rest** with a key from `KeyStore`; `ttl ≤ 60 s` (framework refuses larger). | Code must be created exactly once and visible to the next `consumeCode` on any node. Payload may carry upstream tokens — see _Code payload confidentiality_ in plan. |
21
+ | `TokenStore` | `consumeCode(code)` | **Strong, CAS.** Returns the **decrypted** payload on success. | Single-use; second consumption must fail deterministically. Race with itself must resolve to one winner. |
22
+ | `TokenStore` | `saveRefresh(refresh, payload)` | **Strong, atomic.** | New refresh tokens issued during rotation must be immediately retrievable on the next request. |
23
+ | `TokenStore` | `consumeRefresh(refresh, options)` | **Strong, CAS with reuse-detection window** (default 60 s). | Core of refresh-token rotation security. Concurrent presentations resolve to one winner; reuse within the window triggers the revoke chain. |
24
+ | `TokenStore` | `peekRefresh(refresh)` | **Eventual acceptable.** Non-destructive read; must never mark the token consumed. | Used by `/revoke` for token-to-client binding (RFC 7009 §2.2) and by the refresh-grant for client auth + audit fields. Race losers fall through to `consumeRefresh`, which is the strong gate, so a stale peek can only delay — not bypass — single-use enforcement. |
25
+ | `TokenStore` | `revokeFamily(family)` | Strong preferred; eventual acceptable with documented SLA. | Reuse-detection must invalidate the whole chain. Brief lag is tolerable. |
26
+ | `TokenStore` | `revokeBySubject(tenant, subject)` | Strong preferred; eventual acceptable with documented SLA. | Revocation must propagate quickly. A few seconds of lag is tolerable. |
27
+ | `SessionStore` | `saveFlow(flowId, payload, ttl)` | **Strong, atomic.** `ttl == expiresAt - createdAt`. | Flow record must be visible on the callback request to `consumeFlow`. |
28
+ | `SessionStore` | `updateFlowMethodState(flowId, state)` | **Strong, atomic.** Resolves **before** the user-agent redirect is sent. | Upstream PKCE verifier / nonce must be durably persisted before the redirect, otherwise the callback cannot validate. |
29
+ | `SessionStore` | `consumeFlow(flowId)` | **Strong, atomic delete-on-read** that **returns the full `FlowRecord`** (`CAS` or `DELETE … RETURNING`). | Single-use; concurrent consumption resolves to one winner. The record is returned so the framework can snapshot fields into the auth-code payload before disposal. |
30
+ | `SessionStore` | `createSession / readSession / revokeSession` (optional long-lived) | **Strong.** | Session creation must be immediately readable on the next request. |
31
+ | `KeyStore` | `currentSigningKey()` / `currentEncryptionKey()` | Strong. | Active key must be unambiguous. |
32
+ | `KeyStore` | `signingKeys()` (JWKS) | Eventual OK (with TTL). | Verifiers tolerate brief JWKS lag during rotation. |
33
+ | `KeyStore` | `getEncryptionKey(kid)` | Strong. | Required to decrypt code payloads encrypted under non-current keys during the overlap window. |
34
+ | `ConfigStore` | `getTenantConfig(id)` | **Eventual + bounded staleness (TTL ≤ 60 s).** Invalidation hook fires on update. | Read-heavy, write-rare. Aggressive caching is desirable. |
35
+ | `ConfigStore` | `putTenantConfig(config)` | **Strong write + immediate invalidation** of cached entries for the affected `TenantId`. | Subsequent `getTenantConfig` must reflect the new value once the write resolves. |
36
+ | `MethodStore` | `getMethodConfig` / `listMethods` | Same as `ConfigStore.getTenantConfig`. | Subset of tenant config. |
37
+ | `MethodStore` | `putMethodConfig` / `deleteMethodConfig` | Strong write + immediate invalidation. | Console-driven mutations must take effect on the next request. |
38
+ | `AuditLog` | `log(event)` | Append-only, durable. Cross-instance ordering **not** required (consumers sort by `timestamp` + `actor`). | Loss = audit gap; ordering is a UI / SIEM concern. |
39
+
40
+ ## Implications for adapter choice
41
+
42
+ | Backend | Acceptable for | NOT acceptable for |
43
+ | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
44
+ | **Cloudflare KV** | `ConfigStore`, `MethodStore`, `KeyStore.signingKeys()` (read cache), `AuditLog` (with buffered writes). | `TokenStore.saveCode` / `consumeCode` / `saveRefresh` / `consumeRefresh`, `SessionStore.saveFlow` / `consumeFlow`. Eventual consistency violates these contracts. |
45
+ | **Cloudflare D1** | Everything, **provided** token / code / flow operations use the **D1 Sessions API with bookmarks** (or primary-pinned reads) per AD8. | Token / code / flow operations against non-pinned read replicas without bookmarks. |
46
+ | **Cloudflare Durable Objects** | `SessionStore` (flow records) and `TokenStore` (deployments without D1). | — |
47
+ | **AWS DynamoDB** | Everything, **provided** strong-consistency / conditional-write semantics are used (`ConsistentRead=true`, `ConditionExpression` on CAS). | Default eventual-consistency reads on token / code / flow operations. |
48
+ | **Postgres** | Everything (row-level locking / `SELECT … FOR UPDATE` on the refresh path; `DELETE … RETURNING` on consume paths). | — |
49
+ | **In-memory** | Tests + single-instance dev. Trivially satisfies all contracts (single process). | Multi-instance production. |
50
+
51
+ ### D1 read-replication caveat
52
+
53
+ D1 supports asynchronous read replication. All token / code / flow methods
54
+ above (the security-critical paths) **must** use the D1 Sessions API with
55
+ bookmarks, or primary-pinned reads, to guarantee read-after-write
56
+ consistency. The D1 adapter is certified only when its integration tests
57
+ demonstrate, under simulated replication lag:
58
+
59
+ 1. `consumeCode` / `consumeFlow` immediately after the matching `saveCode` /
60
+ `saveFlow` return the row.
61
+ 2. `consumeRefresh` CAS resolves to exactly one winner under concurrent
62
+ attempts on the same token.
63
+ 3. `revokeBySubject` propagates within the documented SLA.
64
+
65
+ Read-eventual paths (`ConfigStore.getTenantConfig`, JWKS) may use replicas
66
+ freely.
67
+
68
+ Source: <https://developers.cloudflare.com/d1/best-practices/read-replication/>.
69
+
70
+ ## Test fixtures
71
+
72
+ Phase 2 provides parameterized port-conformance tests
73
+ (`packages/openauth/test/ports/`) that run against any adapter. An adapter
74
+ that fails any test in that suite is not certified. Phase 6 adapters must
75
+ pass the full suite against a real (or close-to-real) backend.
76
+
77
+ The fixture set covers, at minimum:
78
+
79
+ - Single-use atomicity of `consumeCode`, `consumeRefresh`, `consumeFlow`
80
+ under concurrent presentations.
81
+ - TTL enforcement (`saveCode` with `ttl > 60` rejected).
82
+ - Encryption-at-rest verification (`consumeCode` returns plaintext only after
83
+ decryption — direct DB inspection shows ciphertext).
84
+ - Refresh reuse detection within the window.
85
+ - `revokeFamily` and `revokeBySubject` propagation.
86
+ - `ConfigStore` invalidation hook fires within bounded staleness.
87
+ - JWKS overlap window — keys retired during the verification window remain
88
+ in `signingKeys()` until removed.
@@ -0,0 +1,148 @@
1
+ /**
2
+ * `AuditLog` — append-only event log for security-relevant operations.
3
+ *
4
+ * Consistency: append-only, durable. Ordering across instances is **not**
5
+ * required; consumers (SIEM, dashboards) sort by `timestamp` and `actor`.
6
+ *
7
+ * Retention: defined by the adapter. 90 days minimum is the documented
8
+ * baseline for SOC 2 readiness.
9
+ *
10
+ * Audit-event payloads must **never** contain auth-code payloads, refresh
11
+ * tokens, access tokens, raw cookies, or any other secret. The framework's
12
+ * built-in events follow this rule; custom emitters must too.
13
+ */
14
+ import type { TenantId } from "../types/tenant"
15
+
16
+ /**
17
+ * Discriminated event union. The framework emits these; user code may emit
18
+ * its own with `kind: "custom"`. Each event carries enough id information
19
+ * for operators to find the offending record without exposing secrets.
20
+ */
21
+ export type AuditEvent =
22
+ | {
23
+ kind: "authorize_started"
24
+ tenantId: TenantId
25
+ clientId: string
26
+ methodId: string
27
+ methodKind: string
28
+ flowId: string
29
+ }
30
+ | {
31
+ kind: "authorize_succeeded"
32
+ tenantId: TenantId
33
+ clientId: string
34
+ methodId: string
35
+ methodKind: string
36
+ flowId: string
37
+ subjectId: string
38
+ }
39
+ | {
40
+ kind: "authorize_failed"
41
+ tenantId: TenantId | null
42
+ clientId: string | null
43
+ methodId?: string
44
+ methodKind?: string
45
+ flowId?: string
46
+ reason: string
47
+ }
48
+ | {
49
+ kind: "token_issued"
50
+ tenantId: TenantId
51
+ clientId: string
52
+ methodId: string
53
+ methodKind: string
54
+ subjectId: string
55
+ /** Hash of the issued refresh token id — never the token itself. */
56
+ refreshTokenIdHash?: string
57
+ }
58
+ | {
59
+ kind: "token_refreshed"
60
+ tenantId: TenantId
61
+ clientId: string
62
+ subjectId: string
63
+ family: string
64
+ }
65
+ | {
66
+ kind: "token_exchanged"
67
+ /** Tenant the new tokens are scoped to. */
68
+ tenantId: TenantId
69
+ /** Tenant the subject_token was originally issued for. */
70
+ fromTenantId: TenantId
71
+ clientId: string
72
+ subjectId: string
73
+ /** Fresh refresh-token family for the issued tokens. */
74
+ family: string
75
+ }
76
+ | {
77
+ kind: "token_revoked"
78
+ tenantId: TenantId
79
+ clientId: string | null
80
+ subjectId?: string
81
+ family?: string
82
+ reason: string
83
+ }
84
+ | {
85
+ kind: "refresh_reuse_detected"
86
+ tenantId: TenantId
87
+ clientId: string
88
+ family: string
89
+ }
90
+ | {
91
+ kind: "flow_replay_attempt"
92
+ tenantId: TenantId | null
93
+ flowId: string
94
+ }
95
+ | {
96
+ kind: "flow_tenant_mismatch"
97
+ stateTenantId: TenantId
98
+ flowTenantId: TenantId
99
+ flowId: string
100
+ }
101
+ | {
102
+ kind: "flow_callback_mismatch"
103
+ tenantId: TenantId
104
+ flowId: string
105
+ expected: { host: string; path: string }
106
+ actual: { host: string; path: string }
107
+ }
108
+ | {
109
+ kind: "factory_id_mismatch"
110
+ tenantId: TenantId
111
+ methodId: string
112
+ expectedKind: string
113
+ actualKind: string
114
+ }
115
+ | {
116
+ kind: "invalid_method_config"
117
+ tenantId: TenantId
118
+ methodId: string
119
+ methodKind: string
120
+ /** Zod error path string. Never the raw config blob. */
121
+ errorPath: string
122
+ }
123
+ | {
124
+ kind: "unknown_method_kind"
125
+ tenantId: TenantId
126
+ methodId: string
127
+ methodKind: string
128
+ }
129
+ | {
130
+ kind: "unrecoverable_flow"
131
+ reason: string
132
+ host?: string
133
+ }
134
+ | {
135
+ kind: "custom"
136
+ type: string
137
+ tenantId?: TenantId
138
+ data: Record<string, unknown>
139
+ }
140
+
141
+ export type AuditLog = {
142
+ /**
143
+ * Append a single event. Should not throw on durability failure; the
144
+ * adapter is responsible for buffering / retry. Returning never-rejects
145
+ * is acceptable so the IdP's hot paths are not gated on the log.
146
+ */
147
+ log(event: AuditEvent & { timestamp: number }): Promise<void>
148
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * `ConfigStore` — tenant configuration lookup.
3
+ *
4
+ * Consistency contract: **eventual + bounded staleness (TTL ≤ 60 s).** This
5
+ * is a read-heavy, write-rare path; Cloudflare KV / read replicas are
6
+ * acceptable. Invalidation hook fires immediately on update so callers can
7
+ * drop stale entries earlier than TTL.
8
+ *
9
+ * See `ports/CONSISTENCY.md` for the full table.
10
+ */
11
+ import type { Result } from "../types/result"
12
+ import type { TenantConfig, TenantId } from "../types/tenant"
13
+
14
+ export type ConfigStore = {
15
+ /**
16
+ * Look up a tenant's full config. Returns `tenant_not_found` if the id is
17
+ * unknown. Implementations should cache aggressively (TTL ≤ 60 s).
18
+ */
19
+ getTenantConfig(id: TenantId): Promise<Result<TenantConfig>>
20
+
21
+ /**
22
+ * Persist (create or update) a tenant's config. Implementations must
23
+ * trigger invalidation of any cached value for `id` before resolving so
24
+ * a subsequent `getTenantConfig` returns the new value.
25
+ */
26
+ putTenantConfig(config: TenantConfig): Promise<Result<void>>
27
+
28
+ /**
29
+ * Optional: signal to in-process caches that a tenant's config has been
30
+ * invalidated externally (e.g. via the management console). Adapters that
31
+ * don't expose cross-process invalidation may omit this.
32
+ */
33
+ onInvalidate?(handler: (id: TenantId) => void): void
34
+ }