@_mustachio/openauth 0.10.0 → 0.12.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 (277) hide show
  1. package/dist/esm/adapters/d1/index.js +18 -9
  2. package/dist/esm/adapters/d1/migrations.js +7 -2
  3. package/dist/esm/adapters/d1/session-store.js +39 -0
  4. package/dist/esm/adapters/d1/session.js +2 -2
  5. package/dist/esm/adapters/durable-object/index.js +4 -0
  6. package/dist/esm/adapters/durable-object/session-store.js +42 -0
  7. package/dist/esm/adapters/dynamo/index.js +24 -7
  8. package/dist/esm/adapters/dynamo/session-store.js +49 -0
  9. package/dist/esm/adapters/kms/index.js +6 -2
  10. package/dist/esm/adapters/kv/index.js +6 -2
  11. package/dist/esm/adapters/memory/index.js +24 -7
  12. package/dist/esm/adapters/memory/session-store.js +45 -0
  13. package/dist/esm/adapters/memory/token-store.js +13 -0
  14. package/dist/esm/adapters/postgres/executor.js +2 -2
  15. package/dist/esm/adapters/postgres/index.js +33 -10
  16. package/dist/esm/adapters/postgres/migrations.js +8 -2
  17. package/dist/esm/adapters/postgres/session-store.js +42 -0
  18. package/dist/esm/client.js +35 -28
  19. package/dist/esm/domain/authorize.js +7 -2
  20. package/dist/esm/domain/callback.js +124 -7
  21. package/dist/esm/domain/client-auth.js +2 -2
  22. package/dist/esm/domain/crypto.js +14 -14
  23. package/dist/esm/domain/discovery.js +46 -4
  24. package/dist/esm/domain/dpop.js +122 -0
  25. package/dist/esm/domain/id-token.js +94 -0
  26. package/dist/esm/domain/introspect.js +5 -1
  27. package/dist/esm/domain/jwt.js +30 -2
  28. package/dist/esm/domain/logout.js +75 -0
  29. package/dist/esm/domain/method-dispatch.js +27 -1
  30. package/dist/esm/domain/method-route.js +83 -1
  31. package/dist/esm/domain/par.js +51 -0
  32. package/dist/esm/domain/pkce.js +2 -2
  33. package/dist/esm/domain/refresh.js +12 -1
  34. package/dist/esm/domain/register.js +74 -0
  35. package/dist/esm/domain/revoke.js +2 -2
  36. package/dist/esm/domain/state-envelope.js +2 -2
  37. package/dist/esm/domain/token-exchange.js +1 -0
  38. package/dist/esm/domain/token.js +53 -12
  39. package/dist/esm/domain/userinfo.js +38 -3
  40. package/dist/esm/error.js +8 -8
  41. package/dist/esm/http/cookies.js +19 -2
  42. package/dist/esm/http/errors.js +4 -4
  43. package/dist/esm/http/handlers/authorize.js +92 -21
  44. package/dist/esm/http/handlers/callback.js +7 -1
  45. package/dist/esm/http/handlers/end-session.js +64 -0
  46. package/dist/esm/http/handlers/metadata.js +7 -4
  47. package/dist/esm/http/handlers/method-route.js +47 -2
  48. package/dist/esm/http/handlers/par.js +53 -0
  49. package/dist/esm/http/handlers/register.js +46 -0
  50. package/dist/esm/http/handlers/revocation.js +2 -2
  51. package/dist/esm/http/handlers/token.js +36 -6
  52. package/dist/esm/http/handlers/userinfo.js +35 -29
  53. package/dist/esm/http/middleware/tenant.js +6 -6
  54. package/dist/esm/http/router.js +10 -0
  55. package/dist/esm/http/schemas/authorize.js +8 -2
  56. package/dist/esm/http/schemas/end-session.js +13 -0
  57. package/dist/esm/http/schemas/par.js +9 -0
  58. package/dist/esm/http/schemas/register.js +16 -0
  59. package/dist/esm/http/schemas/revocation.js +2 -2
  60. package/dist/esm/http/schemas/token.js +7 -7
  61. package/dist/esm/index.js +40 -34
  62. package/dist/esm/methods/oauth2-factory.js +2 -2
  63. package/dist/esm/methods/password-hash.js +2 -2
  64. package/dist/esm/methods/providers/index.js +30 -14
  65. package/dist/esm/methods/saml-sp/acs.js +208 -0
  66. package/dist/esm/methods/saml-sp/attributes.js +75 -0
  67. package/dist/esm/methods/saml-sp/authnrequest.js +63 -0
  68. package/dist/esm/methods/saml-sp/cache-provider.js +33 -0
  69. package/dist/esm/methods/saml-sp/cert-rotation.js +13 -0
  70. package/dist/esm/methods/saml-sp/factory.js +70 -0
  71. package/dist/esm/methods/saml-sp/index.js +7 -0
  72. package/dist/esm/methods/saml-sp/metadata.js +69 -0
  73. package/dist/esm/methods/saml-sp/method.js +29 -0
  74. package/dist/esm/methods/saml-sp/parse-idp-metadata.js +102 -0
  75. package/dist/esm/methods/saml-sp/saml-instance.js +49 -0
  76. package/dist/esm/methods/saml-sp/slo-initiate.js +84 -0
  77. package/dist/esm/methods/saml-sp/sls.js +154 -0
  78. package/dist/esm/methods/saml-sp/types.js +0 -0
  79. package/dist/esm/types/error.js +5 -0
  80. package/dist/esm/types/result.js +3 -3
  81. package/dist/esm/ui/forms.js +3 -3
  82. package/dist/esm/ui/index.js +8 -5
  83. package/dist/esm/ui/picker.js +2 -2
  84. package/dist/types/adapters/d1/migrations.d.ts.map +1 -1
  85. package/dist/types/adapters/d1/session-store.d.ts +3 -0
  86. package/dist/types/adapters/d1/session-store.d.ts.map +1 -1
  87. package/dist/types/adapters/durable-object/session-store.d.ts +3 -0
  88. package/dist/types/adapters/durable-object/session-store.d.ts.map +1 -1
  89. package/dist/types/adapters/dynamo/session-store.d.ts +3 -0
  90. package/dist/types/adapters/dynamo/session-store.d.ts.map +1 -1
  91. package/dist/types/adapters/memory/session-store.d.ts +6 -1
  92. package/dist/types/adapters/memory/session-store.d.ts.map +1 -1
  93. package/dist/types/adapters/memory/token-store.d.ts +1 -0
  94. package/dist/types/adapters/memory/token-store.d.ts.map +1 -1
  95. package/dist/types/adapters/postgres/migrations.d.ts +1 -1
  96. package/dist/types/adapters/postgres/migrations.d.ts.map +1 -1
  97. package/dist/types/adapters/postgres/session-store.d.ts +3 -0
  98. package/dist/types/adapters/postgres/session-store.d.ts.map +1 -1
  99. package/dist/types/client.d.ts +19 -0
  100. package/dist/types/client.d.ts.map +1 -1
  101. package/dist/types/domain/authorize.d.ts.map +1 -1
  102. package/dist/types/domain/callback.d.ts +16 -1
  103. package/dist/types/domain/callback.d.ts.map +1 -1
  104. package/dist/types/domain/client-credentials.d.ts +2 -0
  105. package/dist/types/domain/client-credentials.d.ts.map +1 -1
  106. package/dist/types/domain/discovery.d.ts +37 -0
  107. package/dist/types/domain/discovery.d.ts.map +1 -1
  108. package/dist/types/domain/dpop.d.ts +61 -0
  109. package/dist/types/domain/dpop.d.ts.map +1 -0
  110. package/dist/types/domain/id-token.d.ts +83 -0
  111. package/dist/types/domain/id-token.d.ts.map +1 -0
  112. package/dist/types/domain/introspect.d.ts +8 -0
  113. package/dist/types/domain/introspect.d.ts.map +1 -1
  114. package/dist/types/domain/jwt.d.ts +27 -1
  115. package/dist/types/domain/jwt.d.ts.map +1 -1
  116. package/dist/types/domain/logout.d.ts +69 -0
  117. package/dist/types/domain/logout.d.ts.map +1 -0
  118. package/dist/types/domain/method-dispatch.d.ts.map +1 -1
  119. package/dist/types/domain/method-route.d.ts +57 -1
  120. package/dist/types/domain/method-route.d.ts.map +1 -1
  121. package/dist/types/domain/par.d.ts +62 -0
  122. package/dist/types/domain/par.d.ts.map +1 -0
  123. package/dist/types/domain/refresh.d.ts +9 -0
  124. package/dist/types/domain/refresh.d.ts.map +1 -1
  125. package/dist/types/domain/register.d.ts +33 -0
  126. package/dist/types/domain/register.d.ts.map +1 -0
  127. package/dist/types/domain/token-exchange.d.ts +2 -0
  128. package/dist/types/domain/token-exchange.d.ts.map +1 -1
  129. package/dist/types/domain/token.d.ts +41 -1
  130. package/dist/types/domain/token.d.ts.map +1 -1
  131. package/dist/types/domain/userinfo.d.ts +44 -5
  132. package/dist/types/domain/userinfo.d.ts.map +1 -1
  133. package/dist/types/http/context.d.ts +6 -1
  134. package/dist/types/http/context.d.ts.map +1 -1
  135. package/dist/types/http/cookies.d.ts +9 -1
  136. package/dist/types/http/cookies.d.ts.map +1 -1
  137. package/dist/types/http/handlers/authorize.d.ts.map +1 -1
  138. package/dist/types/http/handlers/callback.d.ts.map +1 -1
  139. package/dist/types/http/handlers/end-session.d.ts +3 -0
  140. package/dist/types/http/handlers/end-session.d.ts.map +1 -0
  141. package/dist/types/http/handlers/metadata.d.ts +1 -1
  142. package/dist/types/http/handlers/metadata.d.ts.map +1 -1
  143. package/dist/types/http/handlers/method-route.d.ts.map +1 -1
  144. package/dist/types/http/handlers/par.d.ts +3 -0
  145. package/dist/types/http/handlers/par.d.ts.map +1 -0
  146. package/dist/types/http/handlers/register.d.ts +3 -0
  147. package/dist/types/http/handlers/register.d.ts.map +1 -0
  148. package/dist/types/http/handlers/token.d.ts.map +1 -1
  149. package/dist/types/http/handlers/userinfo.d.ts.map +1 -1
  150. package/dist/types/http/router.d.ts.map +1 -1
  151. package/dist/types/http/schemas/authorize.d.ts +40 -0
  152. package/dist/types/http/schemas/authorize.d.ts.map +1 -1
  153. package/dist/types/http/schemas/end-session.d.ts +31 -0
  154. package/dist/types/http/schemas/end-session.d.ts.map +1 -0
  155. package/dist/types/http/schemas/par.d.ts +20 -0
  156. package/dist/types/http/schemas/par.d.ts.map +1 -0
  157. package/dist/types/http/schemas/register.d.ts +42 -0
  158. package/dist/types/http/schemas/register.d.ts.map +1 -0
  159. package/dist/types/index.d.ts +3 -3
  160. package/dist/types/index.d.ts.map +1 -1
  161. package/dist/types/methods/saml-sp/acs.d.ts +4 -0
  162. package/dist/types/methods/saml-sp/acs.d.ts.map +1 -0
  163. package/dist/types/methods/saml-sp/attributes.d.ts +40 -0
  164. package/dist/types/methods/saml-sp/attributes.d.ts.map +1 -0
  165. package/dist/types/methods/saml-sp/authnrequest.d.ts +4 -0
  166. package/dist/types/methods/saml-sp/authnrequest.d.ts.map +1 -0
  167. package/dist/types/methods/saml-sp/cache-provider.d.ts +38 -0
  168. package/dist/types/methods/saml-sp/cache-provider.d.ts.map +1 -0
  169. package/dist/types/methods/saml-sp/cert-rotation.d.ts +23 -0
  170. package/dist/types/methods/saml-sp/cert-rotation.d.ts.map +1 -0
  171. package/dist/types/methods/saml-sp/factory.d.ts +704 -0
  172. package/dist/types/methods/saml-sp/factory.d.ts.map +1 -0
  173. package/dist/types/methods/saml-sp/index.d.ts +24 -0
  174. package/dist/types/methods/saml-sp/index.d.ts.map +1 -0
  175. package/dist/types/methods/saml-sp/metadata.d.ts +42 -0
  176. package/dist/types/methods/saml-sp/metadata.d.ts.map +1 -0
  177. package/dist/types/methods/saml-sp/method.d.ts +17 -0
  178. package/dist/types/methods/saml-sp/method.d.ts.map +1 -0
  179. package/dist/types/methods/saml-sp/parse-idp-metadata.d.ts +4 -0
  180. package/dist/types/methods/saml-sp/parse-idp-metadata.d.ts.map +1 -0
  181. package/dist/types/methods/saml-sp/saml-instance.d.ts +81 -0
  182. package/dist/types/methods/saml-sp/saml-instance.d.ts.map +1 -0
  183. package/dist/types/methods/saml-sp/slo-initiate.d.ts +4 -0
  184. package/dist/types/methods/saml-sp/slo-initiate.d.ts.map +1 -0
  185. package/dist/types/methods/saml-sp/sls.d.ts +4 -0
  186. package/dist/types/methods/saml-sp/sls.d.ts.map +1 -0
  187. package/dist/types/methods/saml-sp/types.d.ts +204 -0
  188. package/dist/types/methods/saml-sp/types.d.ts.map +1 -0
  189. package/dist/types/ports/audit-log.d.ts +40 -0
  190. package/dist/types/ports/audit-log.d.ts.map +1 -1
  191. package/dist/types/ports/session-store.d.ts +50 -0
  192. package/dist/types/ports/session-store.d.ts.map +1 -1
  193. package/dist/types/ports/token-store.d.ts +12 -0
  194. package/dist/types/ports/token-store.d.ts.map +1 -1
  195. package/dist/types/types/authorization.d.ts +23 -0
  196. package/dist/types/types/authorization.d.ts.map +1 -1
  197. package/dist/types/types/error.d.ts +9 -0
  198. package/dist/types/types/error.d.ts.map +1 -1
  199. package/dist/types/types/flow.d.ts +10 -0
  200. package/dist/types/types/flow.d.ts.map +1 -1
  201. package/dist/types/types/idp.d.ts +162 -1
  202. package/dist/types/types/idp.d.ts.map +1 -1
  203. package/dist/types/types/method.d.ts +109 -0
  204. package/dist/types/types/method.d.ts.map +1 -1
  205. package/dist/types/types/tenant.d.ts +37 -0
  206. package/dist/types/types/tenant.d.ts.map +1 -1
  207. package/dist/types/types/token.d.ts +128 -0
  208. package/dist/types/types/token.d.ts.map +1 -1
  209. package/package.json +9 -1
  210. package/src/adapters/d1/migrations.ts +5 -0
  211. package/src/adapters/d1/session-store.ts +68 -0
  212. package/src/adapters/durable-object/session-store.ts +61 -0
  213. package/src/adapters/dynamo/session-store.ts +63 -0
  214. package/src/adapters/memory/session-store.ts +83 -1
  215. package/src/adapters/memory/token-store.ts +16 -0
  216. package/src/adapters/postgres/migrations.ts +6 -0
  217. package/src/adapters/postgres/session-store.ts +69 -0
  218. package/src/client.ts +32 -0
  219. package/src/domain/authorize.ts +9 -0
  220. package/src/domain/callback.ts +220 -7
  221. package/src/domain/client-credentials.ts +2 -0
  222. package/src/domain/discovery.ts +80 -2
  223. package/src/domain/dpop.ts +293 -0
  224. package/src/domain/id-token.ts +213 -0
  225. package/src/domain/introspect.ts +10 -0
  226. package/src/domain/jwt.ts +80 -1
  227. package/src/domain/logout.ts +180 -0
  228. package/src/domain/method-dispatch.ts +53 -1
  229. package/src/domain/method-route.ts +195 -1
  230. package/src/domain/par.ts +141 -0
  231. package/src/domain/refresh.ts +41 -0
  232. package/src/domain/register.ts +168 -0
  233. package/src/domain/token-exchange.ts +11 -0
  234. package/src/domain/token.ts +134 -8
  235. package/src/domain/userinfo.ts +121 -6
  236. package/src/http/context.ts +10 -0
  237. package/src/http/cookies.ts +19 -1
  238. package/src/http/handlers/authorize.ts +146 -24
  239. package/src/http/handlers/callback.ts +9 -1
  240. package/src/http/handlers/end-session.ts +106 -0
  241. package/src/http/handlers/metadata.ts +7 -2
  242. package/src/http/handlers/method-route.ts +75 -2
  243. package/src/http/handlers/par.ts +84 -0
  244. package/src/http/handlers/register.ts +70 -0
  245. package/src/http/handlers/token.ts +56 -0
  246. package/src/http/handlers/userinfo.ts +62 -38
  247. package/src/http/router.ts +19 -0
  248. package/src/http/schemas/authorize.ts +27 -0
  249. package/src/http/schemas/end-session.ts +23 -0
  250. package/src/http/schemas/par.ts +23 -0
  251. package/src/http/schemas/register.ts +29 -0
  252. package/src/index.ts +21 -1
  253. package/src/methods/saml-sp/acs.ts +399 -0
  254. package/src/methods/saml-sp/attributes.ts +137 -0
  255. package/src/methods/saml-sp/authnrequest.ts +128 -0
  256. package/src/methods/saml-sp/cache-provider.ts +76 -0
  257. package/src/methods/saml-sp/cert-rotation.ts +34 -0
  258. package/src/methods/saml-sp/factory.ts +118 -0
  259. package/src/methods/saml-sp/index.ts +34 -0
  260. package/src/methods/saml-sp/metadata.ts +204 -0
  261. package/src/methods/saml-sp/method.ts +65 -0
  262. package/src/methods/saml-sp/parse-idp-metadata.ts +164 -0
  263. package/src/methods/saml-sp/saml-instance.ts +173 -0
  264. package/src/methods/saml-sp/slo-initiate.ts +177 -0
  265. package/src/methods/saml-sp/sls.ts +306 -0
  266. package/src/methods/saml-sp/types.ts +203 -0
  267. package/src/ports/CONSISTENCY.md +77 -21
  268. package/src/ports/audit-log.ts +42 -0
  269. package/src/ports/session-store.ts +61 -0
  270. package/src/ports/token-store.ts +13 -0
  271. package/src/types/authorization.ts +25 -0
  272. package/src/types/error.ts +23 -0
  273. package/src/types/flow.ts +10 -0
  274. package/src/types/idp.ts +170 -0
  275. package/src/types/method.ts +110 -0
  276. package/src/types/tenant.ts +37 -0
  277. package/src/types/token.ts +135 -0
@@ -0,0 +1,70 @@
1
+ // src/methods/saml-sp/factory.ts
2
+ import { z } from "zod";
3
+ import { buildSamlSpMethod } from "./method";
4
+ var attributeRefSchema = z.union([
5
+ z.object({ source: z.literal("nameId") }),
6
+ z.object({
7
+ source: z.literal("attribute"),
8
+ name: z.string().min(1),
9
+ format: z.string().optional()
10
+ })
11
+ ]);
12
+ var attributeMappingSchema = z.object({
13
+ subject: attributeRefSchema.optional(),
14
+ email: attributeRefSchema.optional(),
15
+ emailVerified: z.object({ source: z.literal("literal"), value: z.boolean() }).optional(),
16
+ name: attributeRefSchema.optional(),
17
+ groups: attributeRefSchema.optional(),
18
+ custom: z.record(attributeRefSchema).optional()
19
+ });
20
+ var signingCertSchema = z.object({
21
+ pem: z.string().min(1),
22
+ notBefore: z.number().optional(),
23
+ notAfter: z.number().optional()
24
+ });
25
+ var idpSchema = z.object({
26
+ entityId: z.string().min(1),
27
+ ssoUrl: z.string().url(),
28
+ sloUrl: z.string().url().optional(),
29
+ nameIdFormat: z.enum(["persistent", "transient", "emailAddress", "unspecified"]).optional(),
30
+ signingCerts: z.array(signingCertSchema).min(1)
31
+ });
32
+ var idpInitiatedSchema = z.object({
33
+ defaultClientId: z.string().min(1),
34
+ defaultRedirectUri: z.string().url(),
35
+ defaultScopes: z.array(z.string()).optional()
36
+ });
37
+ var samlSpConfigSchema = z.object({
38
+ idp: idpSchema,
39
+ attributeMapping: attributeMappingSchema,
40
+ signAuthnRequest: z.boolean().optional(),
41
+ signingKey: z.object({
42
+ privateKeyPem: z.string().min(1),
43
+ certPem: z.string().min(1)
44
+ }).optional(),
45
+ allowEncryptedAssertions: z.boolean().optional(),
46
+ decryptionKey: z.object({
47
+ privateKeyPem: z.string().min(1),
48
+ certPem: z.string().min(1)
49
+ }).optional(),
50
+ idpInitiated: idpInitiatedSchema.optional(),
51
+ clockSkewSeconds: z.number().int().nonnegative().optional()
52
+ }).refine((c) => !c.signAuthnRequest || c.signingKey !== undefined, {
53
+ message: "signingKey is required when signAuthnRequest is true",
54
+ path: ["signingKey"]
55
+ }).refine((c) => !c.allowEncryptedAssertions || c.decryptionKey !== undefined, {
56
+ message: "decryptionKey is required when allowEncryptedAssertions is true",
57
+ path: ["decryptionKey"]
58
+ });
59
+ var samlSpFactory = {
60
+ kind: "saml-sp",
61
+ configSchema: samlSpConfigSchema,
62
+ build: async ({
63
+ id,
64
+ kind,
65
+ config
66
+ }) => buildSamlSpMethod(id, kind, config)
67
+ };
68
+ export {
69
+ samlSpFactory
70
+ };
@@ -0,0 +1,7 @@
1
+ // src/methods/saml-sp/index.ts
2
+ import { samlSpFactory } from "./factory";
3
+ import { parseSamlIdpMetadata } from "./parse-idp-metadata";
4
+ export {
5
+ parseSamlIdpMetadata,
6
+ samlSpFactory
7
+ };
@@ -0,0 +1,69 @@
1
+ // src/methods/saml-sp/metadata.ts
2
+ import { authError } from "../../types/error";
3
+ import { deriveSpEntityId } from "./saml-instance";
4
+ var NAME_ID_FORMAT_URN = {
5
+ persistent: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
6
+ transient: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
7
+ emailAddress: "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
8
+ unspecified: "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
9
+ };
10
+ var HTTP_POST = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";
11
+ var HTTP_REDIRECT = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect";
12
+ function xmlEscape(s) {
13
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
14
+ }
15
+ function certBody(pem) {
16
+ return pem.replace(/-----BEGIN CERTIFICATE-----/g, "").replace(/-----END CERTIFICATE-----/g, "").replace(/\s+/g, "");
17
+ }
18
+ function buildSpMetadataXml(input) {
19
+ const entityId = xmlEscape(input.spEntityId);
20
+ const acs = xmlEscape(input.acsUrl);
21
+ const signed = input.signingCertPem !== undefined;
22
+ const nameIdLine = input.nameIdFormat !== undefined ? `
23
+ <md:NameIDFormat>${NAME_ID_FORMAT_URN[input.nameIdFormat]}</md:NameIDFormat>` : "";
24
+ const x509 = (cert) => `<ds:KeyInfo><ds:X509Data><ds:X509Certificate>` + certBody(cert) + `</ds:X509Certificate></ds:X509Data></ds:KeyInfo>`;
25
+ const keyDescriptor = (signed ? `
26
+ <md:KeyDescriptor use="signing">` + x509(input.signingCertPem) + `</md:KeyDescriptor>` : "") + (input.encryptionCertPem !== undefined ? `
27
+ <md:KeyDescriptor use="encryption">` + x509(input.encryptionCertPem) + `</md:KeyDescriptor>` : "");
28
+ const sls = input.slsUrl !== undefined ? `
29
+ <md:SingleLogoutService ` + `Binding="${HTTP_REDIRECT}" Location="${xmlEscape(input.slsUrl)}"/>` + `
30
+ <md:SingleLogoutService ` + `Binding="${HTTP_POST}" Location="${xmlEscape(input.slsUrl)}"/>` : "";
31
+ return `<?xml version="1.0" encoding="UTF-8"?>
32
+ ` + `<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ` + `xmlns:ds="http://www.w3.org/2000/09/xmldsig#" ` + `entityID="${entityId}">
33
+ ` + ` <md:SPSSODescriptor AuthnRequestsSigned="${signed}" ` + `WantAssertionsSigned="true" ` + `protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">` + keyDescriptor + sls + nameIdLine + `
34
+ <md:AssertionConsumerService ` + `Binding="${HTTP_POST}" Location="${acs}" index="0" isDefault="true"/>` + `
35
+ </md:SPSSODescriptor>
36
+ ` + `</md:EntityDescriptor>
37
+ `;
38
+ }
39
+ async function buildSpMetadata(ctx, methodId, config) {
40
+ if (!ctx.dispatch) {
41
+ return {
42
+ kind: "error",
43
+ error: authError.internalError("saml-sp: metadata route dispatched without issuer context " + "(ctx.dispatch is null)")
44
+ };
45
+ }
46
+ const spEntityId = deriveSpEntityId(ctx.dispatch.issuerUrl, ctx.tenant.id, methodId);
47
+ const cb = new URL(ctx.dispatch.callbackUrl);
48
+ const slsUrl = `${cb.protocol}//${cb.host}/m/${methodId}/sls`;
49
+ const xml = buildSpMetadataXml({
50
+ spEntityId,
51
+ acsUrl: ctx.dispatch.callbackUrl,
52
+ ...config.idp.sloUrl ? { slsUrl } : {},
53
+ ...config.idp.nameIdFormat !== undefined ? { nameIdFormat: config.idp.nameIdFormat } : {},
54
+ ...config.signAuthnRequest && config.signingKey ? { signingCertPem: config.signingKey.certPem } : {},
55
+ ...config.allowEncryptedAssertions && config.decryptionKey ? { encryptionCertPem: config.decryptionKey.certPem } : {}
56
+ });
57
+ return {
58
+ kind: "challenge",
59
+ response: new Response(xml, {
60
+ status: 200,
61
+ headers: { "content-type": "application/samlmetadata+xml" }
62
+ }),
63
+ cache: { sMaxAge: 300 }
64
+ };
65
+ }
66
+ export {
67
+ buildSpMetadata,
68
+ buildSpMetadataXml
69
+ };
@@ -0,0 +1,29 @@
1
+ // src/methods/saml-sp/method.ts
2
+ import { consumeAssertion } from "./acs";
3
+ import { buildAuthnRequestRedirect } from "./authnrequest";
4
+ import { buildSpMetadata } from "./metadata";
5
+ import { consumeSls } from "./sls";
6
+ import { initiateSpLogout } from "./slo-initiate";
7
+ function buildSamlSpMethod(id, kind, config) {
8
+ return {
9
+ id,
10
+ kind,
11
+ type: "custom",
12
+ routes: {
13
+ "GET /authorize": (ctx) => buildAuthnRequestRedirect(ctx, id, config),
14
+ "GET /callback": (ctx) => consumeAssertion(ctx, id, config),
15
+ "GET /metadata": (ctx) => buildSpMetadata(ctx, id, config),
16
+ "GET /sls": (ctx) => consumeSls(ctx, id, config),
17
+ "POST /sls": (ctx) => consumeSls(ctx, id, config),
18
+ "POST /logout": (ctx) => initiateSpLogout(ctx, id, config)
19
+ },
20
+ publicRoutes: [
21
+ "GET /metadata",
22
+ ...config.idp.sloUrl ? ["GET /sls", "POST /sls", "POST /logout"] : []
23
+ ],
24
+ unsolicitedCallback: config.idpInitiated !== undefined
25
+ };
26
+ }
27
+ export {
28
+ buildSamlSpMethod
29
+ };
@@ -0,0 +1,102 @@
1
+ // src/methods/saml-sp/parse-idp-metadata.ts
2
+ import { authError } from "../../types/error";
3
+ import { err, ok } from "../../types/result";
4
+ import xmldom from "@xmldom/xmldom";
5
+ var { DOMParser } = xmldom;
6
+ var HTTP_REDIRECT = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect";
7
+ var HTTP_POST = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";
8
+ var NAME_ID_FORMAT_BY_URN = {
9
+ "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent": "persistent",
10
+ "urn:oasis:names:tc:SAML:2.0:nameid-format:transient": "transient",
11
+ "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress": "emailAddress",
12
+ "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified": "unspecified"
13
+ };
14
+ function els(root, localName) {
15
+ const list = root.getElementsByTagNameNS("*", localName);
16
+ const out = [];
17
+ for (let i = 0;i < list.length; i++) {
18
+ const n = list[i];
19
+ if (n)
20
+ out.push(n);
21
+ }
22
+ return out;
23
+ }
24
+ function pickEndpoint(endpoints) {
25
+ if (endpoints.length === 0)
26
+ return;
27
+ const byBinding = (b) => endpoints.find((e) => e.getAttribute("Binding") === b);
28
+ const chosen = byBinding(HTTP_REDIRECT) ?? byBinding(HTTP_POST) ?? endpoints[0];
29
+ const loc = chosen?.getAttribute("Location");
30
+ return loc && loc.length > 0 ? loc : undefined;
31
+ }
32
+ function toPem(rawX509) {
33
+ const b64 = rawX509.replace(/\s+/g, "");
34
+ const lines = b64.match(/.{1,64}/g) ?? [b64];
35
+ return `-----BEGIN CERTIFICATE-----
36
+ ` + lines.join(`
37
+ `) + `
38
+ -----END CERTIFICATE-----`;
39
+ }
40
+ function parseSamlIdpMetadata(xml) {
41
+ if (typeof xml !== "string" || xml.trim().length === 0) {
42
+ return err(authError.invalidRequest("metadata XML is empty"));
43
+ }
44
+ let doc;
45
+ try {
46
+ doc = new DOMParser().parseFromString(xml, "text/xml");
47
+ } catch (e) {
48
+ return err(authError.invalidRequest(`metadata XML is not well-formed: ${e instanceof Error ? e.message : String(e)}`));
49
+ }
50
+ if (!doc?.documentElement) {
51
+ return err(authError.invalidRequest("metadata XML has no root element"));
52
+ }
53
+ const entityDescriptor = els(doc, "EntityDescriptor")[0];
54
+ if (!entityDescriptor) {
55
+ return err(authError.invalidRequest("metadata has no <EntityDescriptor>"));
56
+ }
57
+ const entityId = entityDescriptor.getAttribute("entityID");
58
+ if (!entityId) {
59
+ return err(authError.invalidRequest("EntityDescriptor has no entityID"));
60
+ }
61
+ const idp = els(entityDescriptor, "IDPSSODescriptor")[0];
62
+ if (!idp) {
63
+ return err(authError.invalidRequest("not an IdP metadata document (no <IDPSSODescriptor>) — this looks " + "like SP metadata"));
64
+ }
65
+ const ssoUrl = pickEndpoint(els(idp, "SingleSignOnService"));
66
+ if (!ssoUrl) {
67
+ return err(authError.invalidRequest("IDPSSODescriptor has no usable <SingleSignOnService> Location"));
68
+ }
69
+ const sloUrl = pickEndpoint(els(idp, "SingleLogoutService"));
70
+ let nameIdFormat;
71
+ for (const f of els(idp, "NameIDFormat")) {
72
+ const mapped = NAME_ID_FORMAT_BY_URN[(f.textContent ?? "").trim()];
73
+ if (mapped) {
74
+ nameIdFormat = mapped;
75
+ break;
76
+ }
77
+ }
78
+ const signingCerts = [];
79
+ for (const kd of els(idp, "KeyDescriptor")) {
80
+ const use = kd.getAttribute("use");
81
+ if (use && use !== "signing")
82
+ continue;
83
+ for (const cert of els(kd, "X509Certificate")) {
84
+ const body = (cert.textContent ?? "").trim();
85
+ if (body.length > 0)
86
+ signingCerts.push({ pem: toPem(body) });
87
+ }
88
+ }
89
+ if (signingCerts.length === 0) {
90
+ return err(authError.invalidRequest("IDPSSODescriptor has no signing <X509Certificate>"));
91
+ }
92
+ return ok({
93
+ entityId,
94
+ ssoUrl,
95
+ ...sloUrl !== undefined ? { sloUrl } : {},
96
+ ...nameIdFormat !== undefined ? { nameIdFormat } : {},
97
+ signingCerts
98
+ });
99
+ }
100
+ export {
101
+ parseSamlIdpMetadata
102
+ };
@@ -0,0 +1,49 @@
1
+ // src/methods/saml-sp/saml-instance.ts
2
+ import nodeSaml from "@node-saml/node-saml";
3
+ import { methodScratchCacheProvider } from "./cache-provider";
4
+ import { selectActiveCertPems } from "./cert-rotation";
5
+ var { SAML, ValidateInResponseTo } = nodeSaml;
6
+ var NAME_ID_FORMAT_URN = {
7
+ persistent: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
8
+ transient: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
9
+ emailAddress: "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
10
+ unspecified: "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
11
+ };
12
+ var IN_RESPONSE_TO_TTL_MS = 60 * 60 * 1000;
13
+ function deriveSpEntityId(issuerUrl, tenantId, methodId) {
14
+ const base = issuerUrl.endsWith("/") ? issuerUrl.slice(0, -1) : issuerUrl;
15
+ return `${base}/${tenantId}/${methodId}`;
16
+ }
17
+ function buildSamlInstance(config, binding, nowMs) {
18
+ const activeCerts = selectActiveCertPems(config.idp.signingCerts, nowMs);
19
+ if (activeCerts.length === 0) {
20
+ throw new Error("saml-sp: no IdP signing certificate is currently within its " + "validity window — check SamlSpConfig.idp.signingCerts notBefore/notAfter.");
21
+ }
22
+ const identifierFormat = config.idp.nameIdFormat !== undefined ? NAME_ID_FORMAT_URN[config.idp.nameIdFormat] : null;
23
+ return new SAML({
24
+ idpCert: activeCerts,
25
+ issuer: binding.spEntityId,
26
+ callbackUrl: binding.acsUrl,
27
+ entryPoint: config.idp.ssoUrl,
28
+ idpIssuer: config.idp.entityId,
29
+ audience: binding.spEntityId,
30
+ identifierFormat,
31
+ validateInResponseTo: binding.logout ? ValidateInResponseTo.never : binding.idpInitiated ? ValidateInResponseTo.ifPresent : ValidateInResponseTo.always,
32
+ wantAssertionsSigned: true,
33
+ wantAuthnResponseSigned: false,
34
+ acceptedClockSkewMs: (config.clockSkewSeconds ?? 60) * 1000,
35
+ cacheProvider: methodScratchCacheProvider(binding.scratch, IN_RESPONSE_TO_TTL_MS),
36
+ ...binding.signing ? {
37
+ privateKey: binding.signing.privateKeyPem,
38
+ publicCert: binding.signing.certPem,
39
+ signatureAlgorithm: "sha256"
40
+ } : {},
41
+ ...binding.logoutUrl ? { logoutUrl: binding.logoutUrl } : {},
42
+ ...binding.decryptionPvk ? { decryptionPvk: binding.decryptionPvk } : {}
43
+ });
44
+ }
45
+ export {
46
+ NAME_ID_FORMAT_URN,
47
+ buildSamlInstance,
48
+ deriveSpEntityId
49
+ };
@@ -0,0 +1,84 @@
1
+ // src/methods/saml-sp/slo-initiate.ts
2
+ import { authError } from "../../types/error";
3
+ import {
4
+ buildSamlInstance,
5
+ deriveSpEntityId,
6
+ NAME_ID_FORMAT_URN
7
+ } from "./saml-instance";
8
+ async function initiateSpLogout(ctx, methodId, config) {
9
+ if (!ctx.dispatch) {
10
+ return {
11
+ kind: "error",
12
+ error: authError.internalError("saml-sp: /logout dispatched without issuer context (ctx.dispatch is null)")
13
+ };
14
+ }
15
+ if (!config.idp.sloUrl) {
16
+ return {
17
+ kind: "error",
18
+ error: authError.internalError("saml-sp: /logout reached with no idp.sloUrl configured")
19
+ };
20
+ }
21
+ let nameId;
22
+ let sessionIndex;
23
+ let relayState;
24
+ let nameIdFormatParam;
25
+ try {
26
+ const form = new URLSearchParams(await ctx.request.text());
27
+ nameId = form.get("nameId");
28
+ sessionIndex = form.get("sessionIndex");
29
+ relayState = form.get("relayState");
30
+ nameIdFormatParam = form.get("nameIdFormat");
31
+ } catch {
32
+ return {
33
+ kind: "error",
34
+ error: authError.internalError("saml-sp: /logout could not read POST body")
35
+ };
36
+ }
37
+ if (!nameId) {
38
+ return { kind: "denied", reason: "missing nameId" };
39
+ }
40
+ if (nameIdFormatParam !== null && !(nameIdFormatParam in NAME_ID_FORMAT_URN)) {
41
+ return {
42
+ kind: "denied",
43
+ reason: `unrecognized nameIdFormat "${nameIdFormatParam}" — expected one ` + `of: ${Object.keys(NAME_ID_FORMAT_URN).join(", ")}`
44
+ };
45
+ }
46
+ const nameIDFormat = nameIdFormatParam !== null ? NAME_ID_FORMAT_URN[nameIdFormatParam] : config.idp.nameIdFormat !== undefined ? NAME_ID_FORMAT_URN[config.idp.nameIdFormat] : NAME_ID_FORMAT_URN.persistent;
47
+ const spEntityId = deriveSpEntityId(ctx.dispatch.issuerUrl, ctx.tenant.id, methodId);
48
+ let redirectUrl;
49
+ try {
50
+ const saml = buildSamlInstance(config, {
51
+ spEntityId,
52
+ acsUrl: ctx.dispatch.callbackUrl,
53
+ scratch: ctx.methodScratch,
54
+ logoutUrl: config.idp.sloUrl,
55
+ logout: true,
56
+ ...config.signingKey ? {
57
+ signing: {
58
+ privateKeyPem: config.signingKey.privateKeyPem,
59
+ certPem: config.signingKey.certPem
60
+ }
61
+ } : {}
62
+ }, Date.now());
63
+ redirectUrl = await saml.getLogoutUrlAsync({
64
+ nameID: nameId,
65
+ nameIDFormat,
66
+ ...sessionIndex !== null ? { sessionIndex } : {}
67
+ }, relayState ?? "", {});
68
+ } catch (e) {
69
+ return {
70
+ kind: "error",
71
+ error: authError.internalError(`saml-sp: failed to build LogoutRequest: ${e instanceof Error ? e.message : String(e)}`, e)
72
+ };
73
+ }
74
+ return {
75
+ kind: "challenge",
76
+ response: new Response(null, {
77
+ status: 302,
78
+ headers: { location: redirectUrl }
79
+ })
80
+ };
81
+ }
82
+ export {
83
+ initiateSpLogout
84
+ };
@@ -0,0 +1,154 @@
1
+ // src/methods/saml-sp/sls.ts
2
+ import { authError } from "../../types/error";
3
+ import { isErr } from "../../types/result";
4
+ import { buildSamlInstance, deriveSpEntityId } from "./saml-instance";
5
+ var SLO_REPLAY_HORIZON_MS = 10 * 60000;
6
+ async function consumeSls(ctx, methodId, config) {
7
+ if (!ctx.dispatch) {
8
+ return {
9
+ kind: "error",
10
+ error: authError.internalError("saml-sp: /sls dispatched without issuer context (ctx.dispatch is null)")
11
+ };
12
+ }
13
+ if (!config.idp.sloUrl) {
14
+ return {
15
+ kind: "error",
16
+ error: authError.internalError("saml-sp: /sls reached with no idp.sloUrl configured")
17
+ };
18
+ }
19
+ const spEntityId = deriveSpEntityId(ctx.dispatch.issuerUrl, ctx.tenant.id, methodId);
20
+ const url = new URL(ctx.request.url);
21
+ const originalQuery = url.search.replace(/^\?/, "");
22
+ let samlRequest;
23
+ let samlResponse;
24
+ let relayState;
25
+ const isPost = ctx.request.method.toUpperCase() === "POST";
26
+ let postForm = null;
27
+ try {
28
+ if (isPost) {
29
+ postForm = new URLSearchParams(await ctx.request.text());
30
+ samlRequest = postForm.get("SAMLRequest");
31
+ samlResponse = postForm.get("SAMLResponse");
32
+ relayState = postForm.get("RelayState");
33
+ } else {
34
+ samlRequest = url.searchParams.get("SAMLRequest");
35
+ samlResponse = url.searchParams.get("SAMLResponse");
36
+ relayState = url.searchParams.get("RelayState");
37
+ }
38
+ } catch {
39
+ return {
40
+ kind: "error",
41
+ error: authError.internalError("saml-sp: /sls could not read request")
42
+ };
43
+ }
44
+ if (!samlRequest && !samlResponse) {
45
+ return { kind: "denied", reason: "missing SAMLRequest / SAMLResponse" };
46
+ }
47
+ let saml;
48
+ try {
49
+ saml = buildSamlInstance(config, {
50
+ spEntityId,
51
+ acsUrl: ctx.dispatch.callbackUrl,
52
+ scratch: ctx.methodScratch,
53
+ logoutUrl: config.idp.sloUrl,
54
+ logout: true,
55
+ ...config.signingKey ? {
56
+ signing: {
57
+ privateKeyPem: config.signingKey.privateKeyPem,
58
+ certPem: config.signingKey.certPem
59
+ }
60
+ } : {}
61
+ }, Date.now());
62
+ } catch (e) {
63
+ return {
64
+ kind: "error",
65
+ error: authError.internalError(`saml-sp: cannot construct logout verifier: ${e instanceof Error ? e.message : String(e)}`, e)
66
+ };
67
+ }
68
+ if (samlRequest) {
69
+ let profile;
70
+ try {
71
+ const res = isPost ? await saml.validatePostRequestAsync({
72
+ SAMLRequest: samlRequest,
73
+ ...relayState !== null ? { RelayState: relayState } : {}
74
+ }) : await saml.validateRedirectAsync(Object.fromEntries(url.searchParams), originalQuery);
75
+ profile = res.profile;
76
+ } catch (e) {
77
+ return {
78
+ kind: "denied",
79
+ reason: `logout request rejected: ${e instanceof Error ? e.message : String(e)}`
80
+ };
81
+ }
82
+ if (!profile) {
83
+ return { kind: "denied", reason: "logout request produced no profile" };
84
+ }
85
+ if (!profile.ID) {
86
+ return {
87
+ kind: "error",
88
+ error: authError.internalError("saml-sp: LogoutRequest carries no @ID — front-channel replay " + "protection cannot be established. Refusing to process.")
89
+ };
90
+ }
91
+ {
92
+ const key = `slo-replay:${profile.ID}`;
93
+ const seen = await ctx.methodScratch.get(key);
94
+ if (seen.ok) {
95
+ return {
96
+ kind: "denied",
97
+ reason: "logout request replay detected (request ID already seen)"
98
+ };
99
+ }
100
+ const recorded = await ctx.methodScratch.put(key, "1", SLO_REPLAY_HORIZON_MS);
101
+ if (isErr(recorded)) {
102
+ return {
103
+ kind: "error",
104
+ error: authError.internalError("saml-sp: could not record LogoutRequest ID for replay protection")
105
+ };
106
+ }
107
+ }
108
+ let logoutResponseUrl;
109
+ try {
110
+ logoutResponseUrl = await saml.getLogoutResponseUrlAsync(profile, relayState ?? "", {}, true);
111
+ } catch (e) {
112
+ return {
113
+ kind: "error",
114
+ error: authError.internalError(`saml-sp: failed to build LogoutResponse: ${e instanceof Error ? e.message : String(e)}`, e)
115
+ };
116
+ }
117
+ return {
118
+ kind: "challenge",
119
+ response: new Response(null, {
120
+ status: 302,
121
+ headers: { location: logoutResponseUrl }
122
+ }),
123
+ logout: {
124
+ ...profile.nameID !== undefined ? { nameId: profile.nameID } : {},
125
+ ...profile.sessionIndex !== undefined ? { sessionIndex: profile.sessionIndex } : {}
126
+ }
127
+ };
128
+ }
129
+ try {
130
+ if (isPost) {
131
+ await saml.validatePostResponseAsync({
132
+ SAMLResponse: samlResponse,
133
+ ...relayState !== null ? { RelayState: relayState } : {}
134
+ });
135
+ } else {
136
+ await saml.validateRedirectAsync(Object.fromEntries(url.searchParams), originalQuery);
137
+ }
138
+ } catch (e) {
139
+ return {
140
+ kind: "denied",
141
+ reason: `logout response rejected: ${e instanceof Error ? e.message : String(e)}`
142
+ };
143
+ }
144
+ return {
145
+ kind: "challenge",
146
+ response: new Response("Logged out.", {
147
+ status: 200,
148
+ headers: { "content-type": "text/plain" }
149
+ })
150
+ };
151
+ }
152
+ export {
153
+ consumeSls
154
+ };
File without changes
@@ -58,6 +58,11 @@ var authError = {
58
58
  code: "internal_error",
59
59
  description,
60
60
  ...cause !== undefined ? { cause } : {}
61
+ }),
62
+ invalidDpopProof: (description, replaySignal) => ({
63
+ code: "invalid_dpop_proof",
64
+ description,
65
+ ...replaySignal !== undefined ? { replaySignal } : {}
61
66
  })
62
67
  };
63
68
  export {
@@ -4,8 +4,8 @@ var err = (error) => ({ ok: false, error });
4
4
  var isOk = (r) => r.ok === true;
5
5
  var isErr = (r) => r.ok === false;
6
6
  export {
7
- ok,
8
- isOk,
7
+ err,
9
8
  isErr,
10
- err
9
+ isOk,
10
+ ok
11
11
  };
@@ -246,8 +246,8 @@ function renderForm(opts) {
246
246
  });
247
247
  }
248
248
  export {
249
- renderForm,
250
- htmlPage,
249
+ BASE_STYLES,
251
250
  escapeHtml,
252
- BASE_STYLES
251
+ htmlPage,
252
+ renderForm
253
253
  };
@@ -1,8 +1,11 @@
1
+ // src/ui/index.ts
2
+ import { renderForm, escapeHtml, htmlPage, BASE_STYLES } from "./forms";
3
+ import { renderPicker, buildMethodLink } from "./picker";
1
4
  export {
2
- renderPicker,
3
- renderForm,
4
- htmlPage,
5
- escapeHtml,
5
+ BASE_STYLES,
6
6
  buildMethodLink,
7
- BASE_STYLES
7
+ escapeHtml,
8
+ htmlPage,
9
+ renderForm,
10
+ renderPicker
8
11
  };
@@ -44,6 +44,6 @@ function prettyKind(kind) {
44
44
  return kind.split(/[-_]/).map((p) => p.length === 0 ? p : p[0].toUpperCase() + p.slice(1)).join(" ");
45
45
  }
46
46
  export {
47
- renderPicker,
48
- buildMethodLink
47
+ buildMethodLink,
48
+ renderPicker
49
49
  };
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../../src/adapters/d1/migrations.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5C,eAAO,MAAM,kBAAkB,UAkE9B,CAAA;AAED;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,EAAE,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9D"}
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../../src/adapters/d1/migrations.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5C,eAAO,MAAM,kBAAkB,UAuE9B,CAAA;AAED;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,EAAE,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9D"}
@@ -16,5 +16,8 @@ export declare class D1SessionStore implements SessionStore {
16
16
  createSession(sessionId: string, payload: SessionRecord, ttl: number): Promise<Result<void>>;
17
17
  readSession(sessionId: string): Promise<Result<SessionRecord>>;
18
18
  revokeSession(sessionId: string): Promise<Result<void>>;
19
+ saveScratch(key: string, value: string, ttlMs: number): Promise<Result<void>>;
20
+ readScratch(key: string): Promise<Result<string>>;
21
+ deleteScratch(key: string): Promise<Result<void>>;
19
22
  }
20
23
  //# sourceMappingURL=session-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../../../../src/adapters/d1/session-store.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC5E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAIhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5C,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,aAAa,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,MAAM,CAAA;CACrB,CAAA;AAED,qBAAa,cAAe,YAAW,YAAY;;gBAIrC,IAAI,EAAE,qBAAqB;IAKjC,QAAQ,CACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,UAAU,EACnB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAoBlB,qBAAqB,CACzB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAwDlB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IA2BrD,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAuBxD,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,aAAa,EACtB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAuBlB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IA2B9D,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;CAW9D"}
1
+ {"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../../../../src/adapters/d1/session-store.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC5E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAIhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5C,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,aAAa,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,MAAM,CAAA;CACrB,CAAA;AAED,qBAAa,cAAe,YAAW,YAAY;;gBAIrC,IAAI,EAAE,qBAAqB;IAKjC,QAAQ,CACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,UAAU,EACnB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAoBlB,qBAAqB,CACzB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAwDlB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IA2BrD,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAuBxD,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,aAAa,EACtB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAuBlB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IA2B9D,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAYvD,WAAW,CACf,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAyBlB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IA2BjD,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;CAWxD"}
@@ -16,6 +16,9 @@ export declare class DurableObjectSessionStore implements SessionStore {
16
16
  createSession(sessionId: string, payload: SessionRecord, ttl: number): Promise<Result<void>>;
17
17
  readSession(sessionId: string): Promise<Result<SessionRecord>>;
18
18
  revokeSession(sessionId: string): Promise<Result<void>>;
19
+ saveScratch(key: string, value: string, ttlMs: number): Promise<Result<void>>;
20
+ readScratch(key: string): Promise<Result<string>>;
21
+ deleteScratch(key: string): Promise<Result<void>>;
19
22
  }
20
23
  export type { DurableObjectStorageLike, DurableObjectTransactionLike };
21
24
  //# sourceMappingURL=session-store.d.ts.map