@fedify/fedify 2.1.1 → 2.1.3

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 (207) hide show
  1. package/dist/{accept-D7sAxyNa.js → accept-Dd__NiUL.mjs} +10 -8
  2. package/dist/{assert-MZs1qjMx.js → assert-ddO5KLpe.mjs} +5 -9
  3. package/dist/{assert_equals-DSbWqCm3.js → assert_equals-Ew3jOFa3.mjs} +55 -69
  4. package/dist/{assert_instance_of-DHz7EHNU.js → assert_instance_of-C4Ri6VuN.mjs} +5 -9
  5. package/dist/{assert_not_equals-f3m3epl3.js → assert_not_equals--wG9hV7u.mjs} +6 -13
  6. package/dist/{assert_rejects-0h7I2Esa.js → assert_rejects-B-qJtC9Z.mjs} +6 -11
  7. package/dist/{assert_throws-rjdMBf31.js → assert_throws-4NwKEy2q.mjs} +5 -10
  8. package/dist/{builder-DbKYZdSy.js → builder-BKo51w-F.mjs} +32 -41
  9. package/dist/{chunk-CGaQZ11T.cjs → chunk-DDcVe30Y.cjs} +23 -24
  10. package/dist/{chunk-DJNbSFdH.js → chunk-nlSIicah.js} +8 -8
  11. package/dist/{client-BxMZiQaD.d.ts → client-AtlibPOU.d.ts} +1 -1
  12. package/dist/{client-CoCIaTNO.js → client-DEpOVgY1.mjs} +9 -13
  13. package/dist/{client-C97KOq3x.d.cts → client-z-8dc-e1.d.cts} +1 -1
  14. package/dist/{collection-CSzG2j1P.js → collection-BD6-SZ6O.mjs} +7 -12
  15. package/dist/compat/mod.cjs +5 -8
  16. package/dist/compat/mod.d.cts +78 -6
  17. package/dist/compat/mod.d.ts +78 -6
  18. package/dist/compat/mod.js +4 -8
  19. package/dist/compat/transformers.test.mjs +62 -0
  20. package/dist/{context-DyJjQQ_H.d.ts → context-BOiMZBu5.d.ts} +9 -18
  21. package/dist/{context-BcqA-0BL.d.cts → context-BhZVy7RB.d.cts} +9 -18
  22. package/dist/{context-Aqenou7c.js → context-Juj6bdHC.mjs} +7 -11
  23. package/dist/deno-D5r_9RvZ.mjs +8 -0
  24. package/dist/{docloader-Ck0SCLXX.js → docloader-B9CXCw8i.mjs} +8 -14
  25. package/dist/{esm-nLm00z9V.js → esm-DVILvP5e.mjs} +50 -89
  26. package/dist/federation/builder.test.d.mts +2 -0
  27. package/dist/federation/{builder.test.js → builder.test.mjs} +21 -44
  28. package/dist/federation/collection.test.d.mts +2 -0
  29. package/dist/federation/collection.test.mjs +21 -0
  30. package/dist/federation/handler.test.d.mts +2 -0
  31. package/dist/federation/{handler.test.js → handler.test.mjs} +69 -131
  32. package/dist/federation/idempotency.test.d.mts +2 -0
  33. package/dist/federation/{idempotency.test.js → idempotency.test.mjs} +31 -63
  34. package/dist/federation/inbox.test.d.mts +2 -0
  35. package/dist/federation/{inbox.test.js → inbox.test.mjs} +8 -12
  36. package/dist/federation/keycache.test.d.mts +2 -0
  37. package/dist/federation/{keycache.test.js → keycache.test.mjs} +13 -19
  38. package/dist/federation/kv.test.d.mts +2 -0
  39. package/dist/federation/{kv.test.js → kv.test.mjs} +11 -22
  40. package/dist/federation/middleware.test.d.mts +2 -0
  41. package/dist/federation/{middleware.test.js → middleware.test.mjs} +173 -262
  42. package/dist/federation/mod.cjs +327 -16
  43. package/dist/federation/mod.d.cts +3 -6
  44. package/dist/federation/mod.d.ts +3 -6
  45. package/dist/federation/mod.js +322 -13
  46. package/dist/federation/mq.test.d.mts +2 -0
  47. package/dist/federation/{mq.test.js → mq.test.mjs} +21 -35
  48. package/dist/federation/negotiation.test.d.mts +2 -0
  49. package/dist/federation/{negotiation.test.js → negotiation.test.mjs} +9 -16
  50. package/dist/federation/retry.test.d.mts +2 -0
  51. package/dist/federation/{retry.test.js → retry.test.mjs} +8 -11
  52. package/dist/federation/router.test.d.mts +2 -0
  53. package/dist/federation/{router.test.js → router.test.mjs} +11 -16
  54. package/dist/federation/send.test.d.mts +2 -0
  55. package/dist/federation/{send.test.js → send.test.mjs} +22 -30
  56. package/dist/federation/webfinger.test.d.mts +2 -0
  57. package/dist/federation/{webfinger.test.js → webfinger.test.mjs} +22 -56
  58. package/dist/{http-DFzT4YFG.js → http-B53alCGi.mjs} +23 -43
  59. package/dist/{http-ca2xny58.cjs → http-BngkmEhl.cjs} +177 -302
  60. package/dist/{http-BudnHZE2.d.cts → http-CrGuipxe.d.cts} +1 -6
  61. package/dist/{http-EUQ6crVa.js → http-PS3wuU8D.js} +53 -184
  62. package/dist/{http-Dax_FIBo.d.ts → http-aQzN9Ayi.d.ts} +1 -6
  63. package/dist/{inbox-BMLz_-pL.js → inbox-CHsLu5ai.mjs} +18 -26
  64. package/dist/{key-CypuWa94.js → key-D9Np_ZXl.mjs} +29 -37
  65. package/dist/{keycache-CpGWAUbj.js → keycache-CCSwkQcY.mjs} +5 -10
  66. package/dist/{keys-BFve7QQv.js → keys-BAK-tUlf.mjs} +5 -9
  67. package/dist/{kv-BL4nlICN.d.cts → kv-CbLNp3zQ.d.cts} +1 -1
  68. package/dist/{kv-DXEUEP6z.d.ts → kv-GFYnFoOl.d.ts} +1 -1
  69. package/dist/{kv-cache-Bw2F2ABq.js → kv-cache-B01V7s3h.mjs} +4 -8
  70. package/dist/{kv-cache-SKgbvvu4.js → kv-cache-B2Qi5MGv.js} +6 -13
  71. package/dist/{kv-cache-BBJFLMW5.cjs → kv-cache-YCtINZK4.cjs} +27 -34
  72. package/dist/{kv-QzKcOQgP.js → kv-tL2TOE9X.mjs} +6 -10
  73. package/dist/{ld-CXLtTc0G.js → ld-BaxRFhDd.mjs} +17 -31
  74. package/dist/{middleware-CL6XaAFy.cjs → middleware-Bsv-7iX7.cjs} +532 -587
  75. package/dist/middleware-C37OmOz_.mjs +5 -0
  76. package/dist/middleware-CelV2xrI.cjs +4 -0
  77. package/dist/{middleware-CvS6hWm3.js → middleware-Dn1kk96N.js} +335 -382
  78. package/dist/{middleware-BHJ0xm0L.js → middleware-dFn6ozt5.mjs} +282 -317
  79. package/dist/{mod-Bx9jcLB8.d.cts → mod-B505FZBC.d.cts} +3 -3
  80. package/dist/{mod-em2Il1eD.d.cts → mod-Bp_CzKd4.d.cts} +2 -2
  81. package/dist/{mod-Cs2dYEwI.d.ts → mod-D7PAuO6k.d.ts} +3 -3
  82. package/dist/{mod-D6MdymW7.d.ts → mod-DKOAow7a.d.ts} +2 -2
  83. package/dist/{mod-Coe7KEgX.d.cts → mod-DoJBjjnO.d.cts} +2 -2
  84. package/dist/{mod-D6dOd--H.d.ts → mod-DvxszxXC.d.ts} +2 -2
  85. package/dist/mod.cjs +29 -74
  86. package/dist/mod.d.cts +11 -14
  87. package/dist/mod.d.ts +11 -15
  88. package/dist/mod.js +17 -71
  89. package/dist/{negotiation-BlAuS_nr.js → negotiation-DnsfFF8I.mjs} +7 -11
  90. package/dist/nodeinfo/client.test.d.mts +2 -0
  91. package/dist/nodeinfo/{client.test.js → client.test.mjs} +22 -40
  92. package/dist/nodeinfo/handler.test.d.mts +2 -0
  93. package/dist/nodeinfo/{handler.test.js → handler.test.mjs} +13 -43
  94. package/dist/nodeinfo/mod.cjs +5 -8
  95. package/dist/nodeinfo/mod.d.cts +2 -3
  96. package/dist/nodeinfo/mod.d.ts +2 -3
  97. package/dist/nodeinfo/mod.js +4 -8
  98. package/dist/nodeinfo/types.test.d.mts +2 -0
  99. package/dist/nodeinfo/{types.test.js → types.test.mjs} +9 -16
  100. package/dist/otel/exporter.test.d.mts +2 -0
  101. package/dist/otel/{exporter.test.js → exporter.test.mjs} +124 -178
  102. package/dist/otel/mod.cjs +15 -20
  103. package/dist/otel/mod.d.cts +2 -2
  104. package/dist/otel/mod.d.ts +2 -2
  105. package/dist/otel/mod.js +8 -14
  106. package/dist/{owner-gd0Q9FuU.d.ts → owner-74ARJ5TL.d.ts} +1 -1
  107. package/dist/{owner-1AbPBOOZ.d.cts → owner-CptqhsOy.d.cts} +1 -1
  108. package/dist/{owner-CwMai3jn.js → owner-dxM51u36.mjs} +11 -16
  109. package/dist/{proof-ZuJBOUoi.js → proof-CH5U0k7G.mjs} +21 -33
  110. package/dist/{proof-sCID81Ua.cjs → proof-D39qiki3.cjs} +133 -157
  111. package/dist/{proof-6Zw1FW7t.js → proof-Dpgqx9RS.js} +32 -58
  112. package/dist/{retry-mqLf4b-R.js → retry-B_E3V_Dx.mjs} +4 -7
  113. package/dist/{router-D9eI0s4b.js → router-CrMLXoOr.mjs} +4 -8
  114. package/dist/runtime/mod.cjs +11 -13
  115. package/dist/runtime/mod.d.cts +6 -2
  116. package/dist/runtime/mod.d.ts +0 -1
  117. package/dist/runtime/mod.js +4 -7
  118. package/dist/{send-BW73dy6Q.js → send-D1-4ZnQq.mjs} +8 -13
  119. package/dist/sig/accept.test.d.mts +2 -0
  120. package/dist/sig/{accept.test.js → accept.test.mjs} +35 -70
  121. package/dist/sig/http.test.d.mts +2 -0
  122. package/dist/sig/{http.test.js → http.test.mjs} +166 -280
  123. package/dist/sig/key.test.d.mts +2 -0
  124. package/dist/sig/{key.test.js → key.test.mjs} +11 -18
  125. package/dist/sig/ld.test.d.mts +2 -0
  126. package/dist/sig/{ld.test.js → ld.test.mjs} +22 -35
  127. package/dist/sig/mod.cjs +6 -9
  128. package/dist/sig/mod.d.cts +3 -3
  129. package/dist/sig/mod.d.ts +3 -3
  130. package/dist/sig/mod.js +5 -9
  131. package/dist/sig/owner.test.d.mts +2 -0
  132. package/dist/sig/{owner.test.js → owner.test.mjs} +19 -34
  133. package/dist/sig/proof.test.d.mts +2 -0
  134. package/dist/sig/{proof.test.js → proof.test.mjs} +16 -27
  135. package/dist/{std__assert-X-_kMxKM.js → std__assert-Duiq_YC9.mjs} +12 -24
  136. package/dist/testing/{mod.d.ts → mod.d.mts} +26 -90
  137. package/dist/testing/mod.mjs +6 -0
  138. package/dist/{transformers-3g8GZwkZ.cjs → transformers-NeAONrAq.cjs} +20 -25
  139. package/dist/{transformers-C3FLHUd6.js → transformers-ve6e2xcg.js} +3 -7
  140. package/dist/{types-CPz01LGH.js → types-DCP0WLdt.mjs} +4 -7
  141. package/dist/{types-Cd_hszr_.cjs → types-KC4QAoxe.cjs} +29 -34
  142. package/dist/{types-C93Ob9cU.js → types-hvL8ElAs.js} +8 -13
  143. package/dist/utils/docloader.test.d.mts +2 -0
  144. package/dist/utils/{docloader.test.js → docloader.test.mjs} +14 -25
  145. package/dist/utils/kv-cache.test.d.mts +2 -0
  146. package/dist/utils/{kv-cache.test.js → kv-cache.test.mjs} +25 -40
  147. package/dist/utils/mod.cjs +5 -9
  148. package/dist/utils/mod.d.cts +1 -3
  149. package/dist/utils/mod.d.ts +1 -3
  150. package/dist/utils/mod.js +4 -9
  151. package/dist/vocab/cjs.test.d.mts +2 -0
  152. package/dist/vocab/cjs.test.mjs +14 -0
  153. package/dist/vocab/mod.cjs +10 -12
  154. package/dist/vocab/mod.js +3 -5
  155. package/package.json +8 -8
  156. package/dist/compat/transformers.test.d.ts +0 -3
  157. package/dist/compat/transformers.test.js +0 -88
  158. package/dist/compat-Bb4NuTUO.js +0 -4
  159. package/dist/compat-DmDDELst.cjs +0 -4
  160. package/dist/deno-DH972JvX.js +0 -121
  161. package/dist/federation/builder.test.d.ts +0 -3
  162. package/dist/federation/collection.test.d.ts +0 -3
  163. package/dist/federation/collection.test.js +0 -32
  164. package/dist/federation/handler.test.d.ts +0 -3
  165. package/dist/federation/idempotency.test.d.ts +0 -3
  166. package/dist/federation/inbox.test.d.ts +0 -3
  167. package/dist/federation/keycache.test.d.ts +0 -3
  168. package/dist/federation/kv.test.d.ts +0 -3
  169. package/dist/federation/middleware.test.d.ts +0 -3
  170. package/dist/federation/mq.test.d.ts +0 -3
  171. package/dist/federation/negotiation.test.d.ts +0 -3
  172. package/dist/federation/retry.test.d.ts +0 -3
  173. package/dist/federation/router.test.d.ts +0 -3
  174. package/dist/federation/send.test.d.ts +0 -3
  175. package/dist/federation/webfinger.test.d.ts +0 -3
  176. package/dist/federation-Bp3HI26G.cjs +0 -350
  177. package/dist/federation-DaMfqRm4.js +0 -332
  178. package/dist/middleware-B8FJuMM0.js +0 -27
  179. package/dist/middleware-BVp930fR.js +0 -12
  180. package/dist/middleware-BvGP-uXy.cjs +0 -12
  181. package/dist/mod-B7QkWzrL.d.cts +0 -80
  182. package/dist/mod-Bh8mqlYw.d.cts +0 -9
  183. package/dist/mod-D6HodEq7.d.ts +0 -7
  184. package/dist/mod-SMHOMNpZ.d.ts +0 -82
  185. package/dist/mod-gq_Xfdz8.d.cts +0 -1
  186. package/dist/nodeinfo/client.test.d.ts +0 -3
  187. package/dist/nodeinfo/handler.test.d.ts +0 -3
  188. package/dist/nodeinfo/types.test.d.ts +0 -3
  189. package/dist/nodeinfo-DoESQxq5.js +0 -4
  190. package/dist/nodeinfo-DuMYTpbZ.cjs +0 -4
  191. package/dist/otel/exporter.test.d.ts +0 -3
  192. package/dist/runtime-c2Njxsry.cjs +0 -17
  193. package/dist/runtime-poamPCMb.js +0 -13
  194. package/dist/sig/accept.test.d.ts +0 -3
  195. package/dist/sig/http.test.d.ts +0 -3
  196. package/dist/sig/key.test.d.ts +0 -3
  197. package/dist/sig/ld.test.d.ts +0 -3
  198. package/dist/sig/owner.test.d.ts +0 -3
  199. package/dist/sig/proof.test.d.ts +0 -3
  200. package/dist/sig-BNhspNOf.js +0 -4
  201. package/dist/sig-vX39WyWI.cjs +0 -4
  202. package/dist/testing/mod.js +0 -10
  203. package/dist/utils/docloader.test.d.ts +0 -3
  204. package/dist/utils/kv-cache.test.d.ts +0 -3
  205. package/dist/utils-BQ9KqEK9.cjs +0 -4
  206. package/dist/utils-Dn5OPdSW.js +0 -4
  207. /package/dist/{mod-AGjRfPjT.d.ts → compat/transformers.test.d.mts} +0 -0
@@ -1,37 +1,28 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
- import { URLPattern } from "urlpattern-polyfill";
4
- globalThis.addEventListener = () => {};
5
-
6
- import { esm_default } from "../esm-nLm00z9V.js";
7
- import { assertEquals } from "../assert_equals-DSbWqCm3.js";
8
- import { assert } from "../assert-MZs1qjMx.js";
9
- import "../assert_instance_of-DHz7EHNU.js";
10
- import "../deno-DH972JvX.js";
11
- import "../accept-D7sAxyNa.js";
12
- import { exportJwk } from "../key-CypuWa94.js";
13
- import { createRfc9421SignatureBase, doubleKnock, formatRfc9421Signature, formatRfc9421SignatureParameters, parseRfc9421Signature, parseRfc9421SignatureInput, signRequest, timingSafeEqual, verifyRequest, verifyRequestDetailed } from "../http-DFzT4YFG.js";
14
- import { assertExists, assertStringIncludes } from "../std__assert-X-_kMxKM.js";
15
- import { assertFalse, assertRejects } from "../assert_rejects-0h7I2Esa.js";
16
- import { assertThrows } from "../assert_throws-rjdMBf31.js";
17
- import "../assert_not_equals-f3m3epl3.js";
18
- import { rsaPrivateKey2, rsaPublicKey1, rsaPublicKey2, rsaPublicKey5 } from "../keys-BFve7QQv.js";
1
+ import { Temporal } from "@js-temporal/polyfill";
2
+ import "urlpattern-polyfill";
3
+ globalThis.addEventListener = () => {};
4
+ import { t as esm_default } from "../esm-DVILvP5e.mjs";
5
+ import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
6
+ import { a as assertExists, t as assertStringIncludes } from "../std__assert-Duiq_YC9.mjs";
7
+ import { n as assertFalse, t as assertRejects } from "../assert_rejects-B-qJtC9Z.mjs";
8
+ import { t as assertThrows } from "../assert_throws-4NwKEy2q.mjs";
9
+ import { t as assert } from "../assert-ddO5KLpe.mjs";
10
+ import { t as exportJwk } from "../key-D9Np_ZXl.mjs";
11
+ import { a as parseRfc9421Signature, c as timingSafeEqual, i as formatRfc9421SignatureParameters, l as verifyRequest, n as doubleKnock, o as parseRfc9421SignatureInput, r as formatRfc9421Signature, s as signRequest, t as createRfc9421SignatureBase, u as verifyRequestDetailed } from "../http-B53alCGi.mjs";
12
+ import { i as rsaPrivateKey2, l as rsaPublicKey5, o as rsaPublicKey1, s as rsaPublicKey2 } from "../keys-BAK-tUlf.mjs";
19
13
  import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
20
14
  import { FetchError, exportSpki } from "@fedify/vocab-runtime";
21
15
  import { encodeBase64 } from "byte-encodings/base64";
22
-
23
16
  //#region src/sig/http.test.ts
24
17
  test("signRequest() [draft-cavage]", async () => {
25
- const request = new Request("https://example.com/", {
18
+ assertEquals(await verifyRequest(await signRequest(new Request("https://example.com/", {
26
19
  method: "POST",
27
20
  body: "Hello, world!",
28
21
  headers: {
29
22
  "Content-Type": "text/plain; charset=utf-8",
30
23
  Accept: "text/plain"
31
24
  }
32
- });
33
- const signed = await signRequest(request, rsaPrivateKey2, new URL("https://example.com/key2"));
34
- assertEquals(await verifyRequest(signed, {
25
+ }), rsaPrivateKey2, new URL("https://example.com/key2")), {
35
26
  contextLoader: mockDocumentLoader,
36
27
  documentLoader: mockDocumentLoader
37
28
  }), rsaPublicKey2);
@@ -57,8 +48,8 @@ test("verifyRequest() [draft-cavage]", async () => {
57
48
  get(keyId) {
58
49
  return Promise.resolve(cache[keyId.href]);
59
50
  },
60
- set(keyId, key$1) {
61
- cache[keyId.href] = key$1;
51
+ set(keyId, key) {
52
+ cache[keyId.href] = key;
62
53
  return Promise.resolve();
63
54
  }
64
55
  }
@@ -146,7 +137,7 @@ test("verifyRequest() [draft-cavage]", async () => {
146
137
  currentTime: Temporal.Instant.from("2025-01-01T00:00:00.0000Z"),
147
138
  timeWindow: false
148
139
  }), rsaPublicKey1);
149
- const request2 = new Request("https://c27a97f98d5f.ngrok.app/i/inbox", {
140
+ assert(await verifyRequest(new Request("https://c27a97f98d5f.ngrok.app/i/inbox", {
150
141
  method: "POST",
151
142
  body: "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\"],\"actor\":\"https://oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd\",\"object\":{\"actor\":\"https://c27a97f98d5f.ngrok.app/i\",\"object\":\"https://oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd\",\"type\":\"Follow\",\"id\":\"https://c27a97f98d5f.ngrok.app/i#follows/https://oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd\"},\"type\":\"Accept\",\"id\":\"https://oeee.cafe/objects/0fc2608f-5660-4b91-b8c7-63c0c2ac2e20\"}",
152
143
  headers: {
@@ -156,12 +147,10 @@ test("verifyRequest() [draft-cavage]", async () => {
156
147
  Digest: "SHA-256=YZyjeVQW5GwliJowASkteBJhFBTq3eQk/AMqRETc//A=",
157
148
  Signature: "keyId=\"https://oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd#main-key\",algorithm=\"hs2019\",created=\"1756126694\",expires=\"1756130294\",headers=\"(request-target) (created) (expires) content-type date digest host\",signature=\"XFb0jl2uMhE7RhbneE9sK9Zls2qZec8iy6+9O8UgDQeBGJThORFLjXKlps4QO1WAf1YSVB/i5aV6yF+h73Lm3ZiuAJDx1h+00iLsxoYuIw1CZvF0V2jELoo3sQ2/ZzqeoO6H5TbK7tKnU+ulFAPTuJgjIvPwYl11OMRouVS34NiaHP9Yx9pU813TLv37thG/hUKanyq8kk0IJWtDWteY/zxDvzoe7VOkBXVBHslMyrNAI/5JGulVQAQp/E61dJAhTHHIyGxkc/7iutWFZuqFXIiPJ9KR2OuKDj/B32hEzlsf5xH/CjqOJPIg1qMK8FzDiALCq6zjiKIBEnW8HQc/hQ==\""
158
149
  }
159
- });
160
- const options2 = {
150
+ }), {
161
151
  ...options,
162
152
  currentTime: Temporal.Instant.from("2025-08-25T12:58:14Z")
163
- };
164
- assert(await verifyRequest(request2, options2) != null);
153
+ }) != null);
165
154
  });
166
155
  test("verifyRequestDetailed() classifies malformed signatures as invalid", async () => {
167
156
  const draftMissingKeyId = await verifyRequestDetailed(new Request("https://example.com/", {
@@ -214,7 +203,7 @@ test("verifyRequestDetailed() classifies malformed signatures as invalid", async
214
203
  test("verifyRequestDetailed() records failure details on span", async () => {
215
204
  const [tracerProvider, exporter] = createTestTracerProvider();
216
205
  const keyId = new URL("https://gone.example/actors/alice#main-key");
217
- const request = await signRequest(new Request("https://example.com/inbox", {
206
+ assertFalse((await verifyRequestDetailed(await signRequest(new Request("https://example.com/inbox", {
218
207
  method: "POST",
219
208
  headers: {
220
209
  "Content-Type": "application/activity+json",
@@ -225,16 +214,14 @@ test("verifyRequestDetailed() records failure details on span", async () => {
225
214
  type: "Create",
226
215
  actor: "https://gone.example/actors/alice"
227
216
  })
228
- }), rsaPrivateKey2, keyId);
229
- const result = await verifyRequestDetailed(request, {
217
+ }), rsaPrivateKey2, keyId), {
230
218
  tracerProvider,
231
219
  contextLoader: mockDocumentLoader,
232
220
  documentLoader(url) {
233
221
  if (url === keyId.href) throw new FetchError(keyId, `HTTP 410: ${keyId.href}`, new Response(null, { status: 410 }));
234
222
  return mockDocumentLoader(url);
235
223
  }
236
- });
237
- assertFalse(result.verified);
224
+ })).verified);
238
225
  const spans = exporter.getSpans("http_signatures.verify");
239
226
  assertEquals(spans.length, 1);
240
227
  const span = spans[0];
@@ -282,9 +269,7 @@ test("signRequest() and verifyRequest() [rfc9421] implementation", async () => {
282
269
  const contentDigest = signed.headers.get("Content-Digest");
283
270
  assertExists(contentDigest);
284
271
  assert(contentDigest.startsWith("sha-256=:"), "Content-Digest should use RFC 9421 format");
285
- const expectedDigest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(requestBody));
286
- const expectedDigestBase64 = encodeBase64(expectedDigest);
287
- assertEquals(contentDigest, `sha-256=:${expectedDigestBase64}:`, "Content-Digest should have correct value");
272
+ assertEquals(contentDigest, `sha-256=:${encodeBase64(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(requestBody)))}:`, "Content-Digest should have correct value");
288
273
  const signature = signed.headers.get("Signature");
289
274
  assertExists(signature);
290
275
  const sigFormat = /^sig1=:([A-Za-z0-9+/]+=*):/;
@@ -305,25 +290,22 @@ test("signRequest() and verifyRequest() [rfc9421] implementation", async () => {
305
290
  assertEquals(parsedSig.sig1.byteLength > 0, true, "Signature value should be a non-empty Uint8Array");
306
291
  const verifyHeaders = new Headers();
307
292
  for (const [name, value] of signed.headers.entries()) if (name !== "Signature" && name !== "Signature-Input") verifyHeaders.set(name, value);
308
- const reconstructedRequest = new Request(request.url, {
293
+ const reconstructedBase = createRfc9421SignatureBase(new Request(request.url, {
309
294
  method: request.method,
310
295
  headers: verifyHeaders
311
- });
312
- const reconstructedBase = createRfc9421SignatureBase(reconstructedRequest, parsedInput.sig1.components, parsedInput.sig1.parameters);
296
+ }), parsedInput.sig1.components, parsedInput.sig1.parameters);
313
297
  const signatureBytes = new Uint8Array(parsedSig.sig1);
314
- const signatureVerifies = await crypto.subtle.verify("RSASSA-PKCS1-v1_5", rsaPublicKey2.publicKey, signatureBytes, new TextEncoder().encode(reconstructedBase));
315
- assert(signatureVerifies, "Manual verification of signature should succeed");
298
+ assert(await crypto.subtle.verify("RSASSA-PKCS1-v1_5", rsaPublicKey2.publicKey, signatureBytes, new TextEncoder().encode(reconstructedBase)), "Manual verification of signature should succeed");
316
299
  });
317
300
  test("createRfc9421SignatureBase()", () => {
318
- const request = new Request("https://example.com/path?query=value", {
301
+ assertEquals(createRfc9421SignatureBase(new Request("https://example.com/path?query=value", {
319
302
  method: "POST",
320
303
  headers: {
321
304
  Host: "example.com",
322
305
  Date: "Tue, 05 Mar 2024 07:49:44 GMT",
323
306
  "Content-Type": "text/plain"
324
307
  }
325
- });
326
- const components = [
308
+ }), [
327
309
  {
328
310
  value: "@method",
329
311
  params: {}
@@ -340,21 +322,17 @@ test("createRfc9421SignatureBase()", () => {
340
322
  value: "date",
341
323
  params: {}
342
324
  }
343
- ];
344
- const created = 1709626184;
345
- const signatureBase = createRfc9421SignatureBase(request, components, formatRfc9421SignatureParameters({
325
+ ], formatRfc9421SignatureParameters({
346
326
  algorithm: "rsa-v1_5-sha256",
347
327
  keyId: new URL("https://example.com/key"),
348
- created
349
- }));
350
- const expected = [
328
+ created: 1709626184
329
+ })), [
351
330
  `"@method": POST`,
352
331
  `"@target-uri": https://example.com/path?query=value`,
353
332
  `"host": example.com`,
354
333
  `"date": Tue, 05 Mar 2024 07:49:44 GMT`,
355
334
  `"@signature-params": ("@method" "@target-uri" "host" "date");alg="rsa-v1_5-sha256";keyid="https://example.com/key";created=1709626184`
356
- ].join("\n");
357
- assertEquals(signatureBase, expected);
335
+ ].join("\n"));
358
336
  });
359
337
  test("formatRfc9421Signature()", () => {
360
338
  const signature = new Uint8Array([
@@ -365,7 +343,7 @@ test("formatRfc9421Signature()", () => {
365
343
  ]);
366
344
  const keyId = new URL("https://example.com/key");
367
345
  const algorithm = "rsa-v1_5-sha256";
368
- const components = [
346
+ const [signatureInput, signatureHeader] = formatRfc9421Signature(signature, [
369
347
  {
370
348
  "value": "@method",
371
349
  params: {}
@@ -378,19 +356,16 @@ test("formatRfc9421Signature()", () => {
378
356
  "value": "host",
379
357
  params: {}
380
358
  }
381
- ];
382
- const created = 1709626184;
383
- const [signatureInput, signatureHeader] = formatRfc9421Signature(signature, components, formatRfc9421SignatureParameters({
359
+ ], formatRfc9421SignatureParameters({
384
360
  algorithm,
385
361
  keyId,
386
- created
362
+ created: 1709626184
387
363
  }));
388
364
  assertEquals(signatureInput, `sig1=("@method" "@target-uri" "host");alg="rsa-v1_5-sha256";keyid="https://example.com/key";created=1709626184`);
389
365
  assertEquals(signatureHeader, `sig1=:AQIDBA==:`);
390
366
  });
391
367
  test("parseRfc9421SignatureInput()", () => {
392
- const signatureInput = `sig1=("@method" "@target-uri" "host" "date");keyid="https://example.com/key";alg="rsa-v1_5-sha256";created=1709626184`;
393
- const parsed = parseRfc9421SignatureInput(signatureInput);
368
+ const parsed = parseRfc9421SignatureInput(`sig1=("@method" "@target-uri" "host" "date");keyid="https://example.com/key";alg="rsa-v1_5-sha256";created=1709626184`);
394
369
  assertEquals(parsed.sig1.keyId, "https://example.com/key");
395
370
  assertEquals(parsed.sig1.alg, "rsa-v1_5-sha256");
396
371
  assertEquals(parsed.sig1.created, 1709626184);
@@ -415,8 +390,7 @@ test("parseRfc9421SignatureInput()", () => {
415
390
  assertEquals(parsed.sig1.parameters, "keyid=\"https://example.com/key\";alg=\"rsa-v1_5-sha256\";created=1709626184");
416
391
  });
417
392
  test("parseRfc9421Signature()", () => {
418
- const signature = `sig1=:AQIDBA==:,sig2=:Zm9vYmFy:`;
419
- const parsed = parseRfc9421Signature(signature);
393
+ const parsed = parseRfc9421Signature(`sig1=:AQIDBA==:,sig2=:Zm9vYmFy:`);
420
394
  assertExists(parsed.sig1);
421
395
  assertExists(parsed.sig2);
422
396
  const sig1Bytes = new Uint8Array(parsed.sig1);
@@ -425,37 +399,33 @@ test("parseRfc9421Signature()", () => {
425
399
  assertEquals(sig1Bytes[1], 2);
426
400
  assertEquals(sig1Bytes[2], 3);
427
401
  assertEquals(sig1Bytes[3], 4);
428
- const sig2Text = new TextDecoder().decode(parsed.sig2);
429
- assertEquals(sig2Text, "foobar");
402
+ assertEquals(new TextDecoder().decode(parsed.sig2), "foobar");
430
403
  });
431
404
  test("verifyRequest() [rfc9421] successful GET verification", async () => {
432
405
  const currentTimestamp = 1709626184;
433
406
  const currentTime = Temporal.Instant.from("2024-03-05T08:09:44Z");
434
- const validRequest = new Request("https://example.com/api/resource", {
407
+ assertEquals(await verifyRequest(await signRequest(new Request("https://example.com/api/resource", {
435
408
  method: "GET",
436
409
  headers: {
437
410
  "Accept": "application/json",
438
411
  "Host": "example.com",
439
412
  "Date": "Tue, 05 Mar 2024 07:49:44 GMT"
440
413
  }
441
- });
442
- const signedRequest = await signRequest(validRequest, rsaPrivateKey2, new URL("https://example.com/key2"), {
414
+ }), rsaPrivateKey2, new URL("https://example.com/key2"), {
443
415
  spec: "rfc9421",
444
416
  currentTime
445
- });
446
- const verifiedKey = await verifyRequest(signedRequest, {
417
+ }), {
447
418
  contextLoader: mockDocumentLoader,
448
419
  documentLoader: mockDocumentLoader,
449
420
  spec: "rfc9421",
450
421
  currentTime: Temporal.Instant.from(`${(/* @__PURE__ */ new Date(currentTimestamp * 1e3)).toISOString()}`)
451
- });
452
- assertEquals(verifiedKey, rsaPublicKey2, "Valid signature should verify to the correct public key");
422
+ }), rsaPublicKey2, "Valid signature should verify to the correct public key");
453
423
  });
454
424
  test("verifyRequest() [rfc9421] manual POST verification", async () => {
455
425
  const currentTimestamp = 1709626184;
456
426
  const currentTime = Temporal.Instant.from("2024-03-05T08:09:44Z");
457
427
  const postBody = "Test content for signature verification";
458
- const postRequest = new Request("https://example.com/api/resource", {
428
+ const signedPostRequest = await signRequest(new Request("https://example.com/api/resource", {
459
429
  method: "POST",
460
430
  body: postBody,
461
431
  headers: {
@@ -464,8 +434,7 @@ test("verifyRequest() [rfc9421] manual POST verification", async () => {
464
434
  "Host": "example.com",
465
435
  "Date": "Tue, 05 Mar 2024 07:49:44 GMT"
466
436
  }
467
- });
468
- const signedPostRequest = await signRequest(postRequest, rsaPrivateKey2, new URL("https://example.com/key2"), {
437
+ }), rsaPrivateKey2, new URL("https://example.com/key2"), {
469
438
  spec: "rfc9421",
470
439
  currentTime
471
440
  });
@@ -487,61 +456,54 @@ test("verifyRequest() [rfc9421] manual POST verification", async () => {
487
456
  assertExists(parsedSignature.sig1, "Should have a valid signature value");
488
457
  assertEquals(parsedInput.sig1.keyId, "https://example.com/key2", "Signature should have the correct key ID");
489
458
  assertEquals(parsedInput.sig1.created, currentTimestamp, "Signature should have the correct timestamp");
490
- const manualRequest = new Request("https://example.com/api/resource", {
459
+ const signatureBase = createRfc9421SignatureBase(new Request("https://example.com/api/resource", {
491
460
  method: "POST",
492
461
  body: postBody,
493
462
  headers: new Headers(signedPostRequest.headers)
494
- });
495
- const signatureBase = createRfc9421SignatureBase(manualRequest, parsedInput.sig1.components, parsedInput.sig1.parameters);
496
- const signatureVerified = await crypto.subtle.verify("RSASSA-PKCS1-v1_5", rsaPublicKey2.publicKey, parsedSignature.sig1.slice(), new TextEncoder().encode(signatureBase));
497
- assert(signatureVerified, "Manual verification of POST signature should succeed");
463
+ }), parsedInput.sig1.components, parsedInput.sig1.parameters);
464
+ assert(await crypto.subtle.verify("RSASSA-PKCS1-v1_5", rsaPublicKey2.publicKey, parsedSignature.sig1.slice(), new TextEncoder().encode(signatureBase)), "Manual verification of POST signature should succeed");
498
465
  });
499
466
  test("verifyRequest() [rfc9421] error cases and edge cases", async () => {
500
467
  const currentTimestamp = 1709626184;
501
468
  const currentTime = Temporal.Instant.from("2024-03-05T08:09:44Z");
502
- const validRequest = new Request("https://example.com/api/resource", {
469
+ const signedRequest = await signRequest(new Request("https://example.com/api/resource", {
503
470
  method: "GET",
504
471
  headers: {
505
472
  "Accept": "application/json",
506
473
  "Host": "example.com",
507
474
  "Date": "Tue, 05 Mar 2024 07:49:44 GMT"
508
475
  }
509
- });
510
- const signedRequest = await signRequest(validRequest, rsaPrivateKey2, new URL("https://example.com/key2"), {
476
+ }), rsaPrivateKey2, new URL("https://example.com/key2"), {
511
477
  spec: "rfc9421",
512
478
  currentTime
513
479
  });
514
480
  const validSignatureInput = signedRequest.headers.get("Signature-Input") || "";
515
481
  const validSignature = signedRequest.headers.get("Signature") || "";
516
- const missingInputHeader = new Request("https://example.com/api/resource", {
482
+ assertEquals(await verifyRequest(new Request("https://example.com/api/resource", {
517
483
  method: "GET",
518
484
  headers: new Headers({
519
485
  "Accept": "application/json",
520
486
  "Host": "example.com",
521
487
  "Signature": validSignature
522
488
  })
523
- });
524
- const missingInputResult = await verifyRequest(missingInputHeader, {
489
+ }), {
525
490
  contextLoader: mockDocumentLoader,
526
491
  documentLoader: mockDocumentLoader,
527
492
  spec: "rfc9421"
528
- });
529
- assertEquals(missingInputResult, null, "Should fail verification when Signature-Input header is missing");
530
- const missingSignatureHeader = new Request("https://example.com/api/resource", {
493
+ }), null, "Should fail verification when Signature-Input header is missing");
494
+ assertEquals(await verifyRequest(new Request("https://example.com/api/resource", {
531
495
  method: "GET",
532
496
  headers: new Headers({
533
497
  "Accept": "application/json",
534
498
  "Host": "example.com",
535
499
  "Signature-Input": validSignatureInput
536
500
  })
537
- });
538
- const missingSignatureResult = await verifyRequest(missingSignatureHeader, {
501
+ }), {
539
502
  contextLoader: mockDocumentLoader,
540
503
  documentLoader: mockDocumentLoader,
541
504
  spec: "rfc9421"
542
- });
543
- assertEquals(missingSignatureResult, null, "Should fail verification when Signature header is missing");
544
- const tamperedRequest = new Request("https://example.com/api/resource", {
505
+ }), null, "Should fail verification when Signature header is missing");
506
+ assertEquals(await verifyRequest(new Request("https://example.com/api/resource", {
545
507
  method: "GET",
546
508
  headers: new Headers({
547
509
  "Accept": "application/json",
@@ -550,14 +512,12 @@ test("verifyRequest() [rfc9421] error cases and edge cases", async () => {
550
512
  "Signature-Input": validSignatureInput,
551
513
  "Signature": "sig1=:AAAAAA==:"
552
514
  })
553
- });
554
- const tamperedResult = await verifyRequest(tamperedRequest, {
515
+ }), {
555
516
  contextLoader: mockDocumentLoader,
556
517
  documentLoader: mockDocumentLoader,
557
518
  spec: "rfc9421"
558
- });
559
- assertEquals(tamperedResult, null, "Should fail verification when signature is tampered");
560
- const expiredRequest = new Request("https://example.com/api/resource", {
519
+ }), null, "Should fail verification when signature is tampered");
520
+ assertEquals(await verifyRequest(new Request("https://example.com/api/resource", {
561
521
  method: "GET",
562
522
  headers: new Headers({
563
523
  "Accept": "application/json",
@@ -566,16 +526,14 @@ test("verifyRequest() [rfc9421] error cases and edge cases", async () => {
566
526
  "Signature-Input": validSignatureInput,
567
527
  "Signature": validSignature
568
528
  })
569
- });
570
- const expiredResult = await verifyRequest(expiredRequest, {
529
+ }), {
571
530
  contextLoader: mockDocumentLoader,
572
531
  documentLoader: mockDocumentLoader,
573
532
  spec: "rfc9421",
574
533
  currentTime: Temporal.Instant.from(`${(/* @__PURE__ */ new Date((currentTimestamp + 2592e3) * 1e3)).toISOString()}`),
575
534
  timeWindow: { hours: 1 }
576
- });
577
- assertEquals(expiredResult, null, "Should fail verification when signature timestamp is too old");
578
- const futureRequest = new Request("https://example.com/api/resource", {
535
+ }), null, "Should fail verification when signature timestamp is too old");
536
+ assertEquals(await verifyRequest(new Request("https://example.com/api/resource", {
579
537
  method: "GET",
580
538
  headers: new Headers({
581
539
  "Accept": "application/json",
@@ -584,16 +542,14 @@ test("verifyRequest() [rfc9421] error cases and edge cases", async () => {
584
542
  "Signature-Input": validSignatureInput,
585
543
  "Signature": validSignature
586
544
  })
587
- });
588
- const futureResult = await verifyRequest(futureRequest, {
545
+ }), {
589
546
  contextLoader: mockDocumentLoader,
590
547
  documentLoader: mockDocumentLoader,
591
548
  spec: "rfc9421",
592
549
  currentTime: Temporal.Instant.from(`${(/* @__PURE__ */ new Date((currentTimestamp - 2592e3) * 1e3)).toISOString()}`),
593
550
  timeWindow: { hours: 1 }
594
- });
595
- assertEquals(futureResult, null, "Should fail verification when signature timestamp is in the future");
596
- const timeCheckRequest = new Request("https://example.com/api/resource", {
551
+ }), null, "Should fail verification when signature timestamp is in the future");
552
+ assertEquals(await verifyRequest(new Request("https://example.com/api/resource", {
597
553
  method: "GET",
598
554
  headers: new Headers({
599
555
  "Accept": "application/json",
@@ -602,16 +558,14 @@ test("verifyRequest() [rfc9421] error cases and edge cases", async () => {
602
558
  "Signature-Input": validSignatureInput,
603
559
  "Signature": validSignature
604
560
  })
605
- });
606
- const timeDisabledResult = await verifyRequest(timeCheckRequest, {
561
+ }), {
607
562
  contextLoader: mockDocumentLoader,
608
563
  documentLoader: mockDocumentLoader,
609
564
  spec: "rfc9421",
610
565
  currentTime: Temporal.Instant.from(`${(/* @__PURE__ */ new Date((currentTimestamp + 31536e3) * 1e3)).toISOString()}`),
611
566
  timeWindow: false
612
- });
613
- assertEquals(timeDisabledResult, rsaPublicKey2, "Should verify signature when time checking is disabled");
614
- const postRequest = new Request("https://example.com/api/resource", {
567
+ }), rsaPublicKey2, "Should verify signature when time checking is disabled");
568
+ const freshSignedPostRequest = await signRequest(new Request("https://example.com/api/resource", {
615
569
  method: "POST",
616
570
  body: "Test content for signature verification",
617
571
  headers: {
@@ -620,15 +574,14 @@ test("verifyRequest() [rfc9421] error cases and edge cases", async () => {
620
574
  "Host": "example.com",
621
575
  "Date": "Tue, 05 Mar 2024 07:49:44 GMT"
622
576
  }
623
- });
624
- const freshSignedPostRequest = await signRequest(postRequest, rsaPrivateKey2, new URL("https://example.com/key2"), {
577
+ }), rsaPrivateKey2, new URL("https://example.com/key2"), {
625
578
  spec: "rfc9421",
626
579
  currentTime
627
580
  });
628
581
  const postSignatureInput = freshSignedPostRequest.headers.get("Signature-Input") || "";
629
582
  const postSignature = freshSignedPostRequest.headers.get("Signature") || "";
630
583
  const postContentDigest = freshSignedPostRequest.headers.get("Content-Digest") || "";
631
- const tamperDigestRequest = new Request("https://example.com/api/resource", {
584
+ assertEquals(await verifyRequest(new Request("https://example.com/api/resource", {
632
585
  method: "POST",
633
586
  body: "This content won't match the digest",
634
587
  headers: new Headers({
@@ -639,22 +592,19 @@ test("verifyRequest() [rfc9421] error cases and edge cases", async () => {
639
592
  "Signature": postSignature,
640
593
  "Content-Digest": postContentDigest
641
594
  })
642
- });
643
- const tamperDigestResult = await verifyRequest(tamperDigestRequest, {
595
+ }), {
644
596
  contextLoader: mockDocumentLoader,
645
597
  documentLoader: mockDocumentLoader,
646
598
  spec: "rfc9421",
647
599
  currentTime: Temporal.Instant.from(`${(/* @__PURE__ */ new Date(currentTimestamp * 1e3)).toISOString()}`)
648
- });
649
- assertEquals(tamperDigestResult, null, "Should fail verification with invalid Content-Digest");
600
+ }), null, "Should fail verification with invalid Content-Digest");
650
601
  const testRequest = new Request("https://example.com/", { headers: new Headers({
651
602
  "Date": "Tue, 05 Mar 2024 07:49:44 GMT",
652
603
  "Host": "example.com",
653
604
  "Signature-Input": `sig1=("@method" "@target-uri" "host" "date");keyid="https://example.com/key";alg="rsa-v1_5-sha256";created=1709626184`,
654
605
  "Signature": `sig1=:YXNkZmprc2RmaGprc2RoZmprc2hkZmtqaHNkZg==:`
655
606
  }) });
656
- const signatureInput = testRequest.headers.get("Signature-Input") || "";
657
- const parsedInput = parseRfc9421SignatureInput(signatureInput);
607
+ const parsedInput = parseRfc9421SignatureInput(testRequest.headers.get("Signature-Input") || "");
658
608
  assertExists(parsedInput.sig1);
659
609
  assertEquals(parsedInput.sig1.keyId, "https://example.com/key");
660
610
  assertEquals(parsedInput.sig1.alg, "rsa-v1_5-sha256");
@@ -677,12 +627,10 @@ test("verifyRequest() [rfc9421] error cases and edge cases", async () => {
677
627
  params: {}
678
628
  }
679
629
  ]);
680
- const signature = testRequest.headers.get("Signature") || "";
681
- const parsedSig = parseRfc9421Signature(signature);
630
+ const parsedSig = parseRfc9421Signature(testRequest.headers.get("Signature") || "");
682
631
  assertExists(parsedSig.sig1);
683
632
  assert(new TextDecoder().decode(parsedSig.sig1).length > 0, "Signature base64 should decode to non-empty string");
684
- const complexSignatureInput = "sig1=(\"@method\" \"@target-uri\" \"host\" \"content-type\" \"value with \\\"quotes\\\" and spaces\");keyid=\"https://example.com/key with spaces\";alg=\"rsa-v1_5-sha256\";created=1709626184";
685
- const complexParsedInput = parseRfc9421SignatureInput(complexSignatureInput);
633
+ const complexParsedInput = parseRfc9421SignatureInput("sig1=(\"@method\" \"@target-uri\" \"host\" \"content-type\" \"value with \\\"quotes\\\" and spaces\");keyid=\"https://example.com/key with spaces\";alg=\"rsa-v1_5-sha256\";created=1709626184");
686
634
  assertExists(complexParsedInput.sig1);
687
635
  assertEquals(complexParsedInput.sig1.keyId, "https://example.com/key with spaces");
688
636
  assertEquals(complexParsedInput.sig1.alg, "rsa-v1_5-sha256");
@@ -701,16 +649,13 @@ test("verifyRequest() [rfc9421] error cases and edge cases", async () => {
701
649
  assertEquals(multiParsedInput.sig2.alg, "rsa-pss-sha512");
702
650
  const multiParsedSig = parseRfc9421Signature(multiSigRequest.headers.get("Signature") || "");
703
651
  assertEquals(Object.keys(multiParsedSig).length, 2, "Should parse multiple signature values");
704
- const invalidInputFormat = "this is not a valid signature-input format";
705
- const parsedInvalidInput = parseRfc9421SignatureInput(invalidInputFormat);
652
+ const parsedInvalidInput = parseRfc9421SignatureInput("this is not a valid signature-input format");
706
653
  assertEquals(Object.keys(parsedInvalidInput).length, 0, "Should handle invalid Signature-Input format");
707
- const invalidSigFormat = "this is not a valid signature format";
708
- const parsedInvalidSig = parseRfc9421Signature(invalidSigFormat);
654
+ const parsedInvalidSig = parseRfc9421Signature("this is not a valid signature format");
709
655
  assertEquals(Object.keys(parsedInvalidSig).length, 0, "Should handle invalid Signature format");
710
- const invalidBase64Sig = "sig1=:!@#$%%^&*():";
711
- const parsedInvalidBase64 = parseRfc9421Signature(invalidBase64Sig);
656
+ const parsedInvalidBase64 = parseRfc9421Signature("sig1=:!@#$%%^&*():");
712
657
  assertEquals(Object.keys(parsedInvalidBase64).length, 0, "Should handle invalid base64 in signature");
713
- const mixedRequest = new Request("https://example.com/api/resource", {
658
+ assertEquals(await verifyRequest(new Request("https://example.com/api/resource", {
714
659
  method: "GET",
715
660
  headers: new Headers({
716
661
  "Accept": "application/json",
@@ -719,14 +664,12 @@ test("verifyRequest() [rfc9421] error cases and edge cases", async () => {
719
664
  "Signature-Input": `${validSignatureInput},sig2=("@method" "@target-uri" "host" "date");keyid="https://example.com/invalid-key";alg="rsa-v1_5-sha256";created=${currentTimestamp}`,
720
665
  "Signature": `${validSignature},sig2=:AAAAAA==:`
721
666
  })
722
- });
723
- const mixedResult = await verifyRequest(mixedRequest, {
667
+ }), {
724
668
  contextLoader: mockDocumentLoader,
725
669
  documentLoader: mockDocumentLoader,
726
670
  spec: "rfc9421",
727
671
  currentTime: Temporal.Instant.from(`${(/* @__PURE__ */ new Date(currentTimestamp * 1e3)).toISOString()}`)
728
- });
729
- assertEquals(mixedResult, rsaPublicKey2, "Should verify when at least one signature is valid");
672
+ }), rsaPublicKey2, "Should verify when at least one signature is valid");
730
673
  });
731
674
  test("verifyRequest() [rfc9421] test vector from Mastodon", async () => {
732
675
  const signedRequest = new Request("https://www.example.com/activitypub/success", {
@@ -789,14 +732,13 @@ test("doubleKnock() function with successful first attempt", async () => {
789
732
  const logFunction = (req) => {
790
733
  loggedRequest = req;
791
734
  };
792
- const response = await doubleKnock(request, {
735
+ assertEquals((await doubleKnock(request, {
793
736
  keyId: rsaPublicKey2.id,
794
737
  privateKey: rsaPrivateKey2
795
738
  }, {
796
739
  specDeterminer,
797
740
  log: logFunction
798
- });
799
- assertEquals(response.status, 202, "Response status should be 202 Accepted");
741
+ })).status, 202, "Response status should be 202 Accepted");
800
742
  assertEquals(requestCount, 1, "Only one request should have been made");
801
743
  assertEquals(firstRequestSpec, "rfc9421", "First attempt should use RFC 9421");
802
744
  assertEquals(specDeterminer.usedSpec, "rfc9421", "Spec should be remembered");
@@ -837,11 +779,10 @@ test("doubleKnock() function with fallback to draft-cavage", async () => {
837
779
  this.rememberedSpec = spec;
838
780
  }
839
781
  };
840
- const response = await doubleKnock(request, {
782
+ assertEquals((await doubleKnock(request, {
841
783
  keyId: rsaPublicKey2.id,
842
784
  privateKey: rsaPrivateKey2
843
- }, { specDeterminer });
844
- assertEquals(response.status, 202, "Response status should be 202 Accepted");
785
+ }, { specDeterminer })).status, 202, "Response status should be 202 Accepted");
845
786
  assertEquals(requestCount, 2, "Two requests should have been made");
846
787
  assertEquals(firstSpec, "rfc9421", "First attempt should use RFC 9421");
847
788
  assertEquals(secondSpec, "draft-cavage-http-signatures-12", "Second attempt should use draft-cavage");
@@ -863,16 +804,14 @@ test("doubleKnock() function with redirect handling", async () => {
863
804
  responseCodes.push(202);
864
805
  return new Response("", { status: 202 });
865
806
  });
866
- const request = new Request("https://example.com/redirect-endpoint", {
807
+ assertEquals((await doubleKnock(new Request("https://example.com/redirect-endpoint", {
867
808
  method: "POST",
868
809
  body: "Test message that will be redirected",
869
810
  headers: { "Content-Type": "text/plain" }
870
- });
871
- const response = await doubleKnock(request, {
811
+ }), {
872
812
  keyId: rsaPublicKey2.id,
873
813
  privateKey: rsaPrivateKey2
874
- });
875
- assertEquals(response.status, 202, "Final response status should be 202 Accepted");
814
+ })).status, 202, "Final response status should be 202 Accepted");
876
815
  assertEquals(requestedUrls.length, 2, "Two URLs should have been requested");
877
816
  assertEquals(requestedUrls[0], "https://example.com/redirect-endpoint", "First request should be to redirect-endpoint");
878
817
  assertEquals(requestedUrls[1], "https://example.com/final-endpoint", "Second request should be to final-endpoint");
@@ -891,16 +830,14 @@ test("doubleKnock() function with both specs rejected", async () => {
891
830
  else attempts.push("unknown");
892
831
  return new Response("Unauthorized", { status: 401 });
893
832
  });
894
- const request = new Request("https://example.com/inbox-rejects-all", {
833
+ assertEquals((await doubleKnock(new Request("https://example.com/inbox-rejects-all", {
895
834
  method: "POST",
896
835
  body: "Test message that will be rejected regardless of signature format",
897
836
  headers: { "Content-Type": "text/plain" }
898
- });
899
- const response = await doubleKnock(request, {
837
+ }), {
900
838
  keyId: rsaPublicKey2.id,
901
839
  privateKey: rsaPrivateKey2
902
- });
903
- assertEquals(response.status, 401, "Final response status should be 401 Unauthorized");
840
+ })).status, 401, "Final response status should be 401 Unauthorized");
904
841
  assertEquals(requestCount, 2, "Two requests should have been made");
905
842
  assertEquals(attempts.length, 2, "Two signature attempts should have been made");
906
843
  assertEquals(attempts[0], "rfc9421", "First attempt should use RFC 9421");
@@ -924,16 +861,14 @@ test("doubleKnock() function with specDeterminer choosing draft-cavage first", a
924
861
  },
925
862
  rememberSpec(_origin, _spec) {}
926
863
  };
927
- const request = new Request("https://example.com/inbox-accepts-any", {
864
+ assertEquals((await doubleKnock(new Request("https://example.com/inbox-accepts-any", {
928
865
  method: "POST",
929
866
  body: "Test message with draft-cavage preference",
930
867
  headers: { "Content-Type": "text/plain" }
931
- });
932
- const response = await doubleKnock(request, {
868
+ }), {
933
869
  keyId: rsaPublicKey2.id,
934
870
  privateKey: rsaPrivateKey2
935
- }, { specDeterminer });
936
- assertEquals(response.status, 202, "Response status should be 202 Accepted");
871
+ }, { specDeterminer })).status, 202, "Response status should be 202 Accepted");
937
872
  assertEquals(requestCount, 1, "Only one request should have been made");
938
873
  assertEquals(firstSpec, "draft-cavage", "First attempt should use draft-cavage");
939
874
  esm_default.hardReset();
@@ -1044,25 +979,21 @@ test("doubleKnock() async specDeterminer test", async () => {
1044
979
  await new Promise((resolve) => setTimeout(resolve, 10));
1045
980
  }
1046
981
  };
1047
- const request = new Request("https://example.com/inbox-async-determiner", {
982
+ assertEquals((await doubleKnock(new Request("https://example.com/inbox-async-determiner", {
1048
983
  method: "POST",
1049
984
  body: "Test message with async spec determiner",
1050
985
  headers: { "Content-Type": "text/plain" }
1051
- });
1052
- const response = await doubleKnock(request, {
986
+ }), {
1053
987
  keyId: rsaPublicKey2.id,
1054
988
  privateKey: rsaPrivateKey2
1055
- }, { specDeterminer });
1056
- assertEquals(response.status, 202, "Response status should be 202 Accepted");
989
+ }, { specDeterminer })).status, 202, "Response status should be 202 Accepted");
1057
990
  assertEquals(requestCount, 1, "Only one request should have been made");
1058
991
  assertEquals(specUsed, "draft-cavage-http-signatures-12", "Should use spec from async determiner");
1059
992
  esm_default.hardReset();
1060
993
  });
1061
994
  test("timingSafeEqual()", async (t) => {
1062
995
  await t.step("should return true for equal empty arrays", () => {
1063
- const a = new Uint8Array([]);
1064
- const b = new Uint8Array([]);
1065
- assert(timingSafeEqual(a, b));
996
+ assert(timingSafeEqual(new Uint8Array([]), new Uint8Array([])));
1066
997
  });
1067
998
  await t.step("should return true for equal non-empty arrays", async (t2) => {
1068
999
  const testCases = [
@@ -1129,7 +1060,7 @@ test("timingSafeEqual()", async (t) => {
1129
1060
  assert(timingSafeEqual(arr, arr), "Array should be equal to itself by reference");
1130
1061
  });
1131
1062
  await t.step("should return false for arrays with same length but different content", async (t2) => {
1132
- const testCases = [
1063
+ for (const tc of [
1133
1064
  {
1134
1065
  a: [
1135
1066
  1,
@@ -1187,13 +1118,12 @@ test("timingSafeEqual()", async (t) => {
1187
1118
  ],
1188
1119
  name: "middle byte differs with edge values"
1189
1120
  }
1190
- ];
1191
- for (const tc of testCases) await t2.step(tc.name, () => {
1121
+ ]) await t2.step(tc.name, () => {
1192
1122
  assertFalse(timingSafeEqual(new Uint8Array(tc.a), new Uint8Array(tc.b)));
1193
1123
  });
1194
1124
  });
1195
1125
  await t.step("should return false for arrays with different lengths", async (t2) => {
1196
- const testCases = [
1126
+ for (const tc of [
1197
1127
  {
1198
1128
  a: [
1199
1129
  1,
@@ -1230,13 +1160,12 @@ test("timingSafeEqual()", async (t) => {
1230
1160
  b: [],
1231
1161
  name: "a non-empty, b empty"
1232
1162
  }
1233
- ];
1234
- for (const tc of testCases) await t2.step(tc.name, () => {
1163
+ ]) await t2.step(tc.name, () => {
1235
1164
  assertFalse(timingSafeEqual(new Uint8Array(tc.a), new Uint8Array(tc.b)));
1236
1165
  });
1237
1166
  });
1238
1167
  await t.step("should return false where content matches up to shorter length", async (t2) => {
1239
- const testCases = [
1168
+ for (const tc of [
1240
1169
  {
1241
1170
  a: [1, 2],
1242
1171
  b: [
@@ -1265,21 +1194,16 @@ test("timingSafeEqual()", async (t) => {
1265
1194
  b: [0],
1266
1195
  name: "two zeros vs single zero"
1267
1196
  }
1268
- ];
1269
- for (const tc of testCases) await t2.step(tc.name, () => {
1197
+ ]) await t2.step(tc.name, () => {
1270
1198
  assertFalse(timingSafeEqual(new Uint8Array(tc.a), new Uint8Array(tc.b)));
1271
1199
  });
1272
1200
  });
1273
1201
  await t.step("should correctly handle comparisons involving padding bytes", async (t2) => {
1274
1202
  await t2.step("a=[1], b=[1,0] (b longer with trailing zero)", () => {
1275
- const a1 = new Uint8Array([1]);
1276
- const b1 = new Uint8Array([1, 0]);
1277
- assertFalse(timingSafeEqual(a1, b1));
1203
+ assertFalse(timingSafeEqual(new Uint8Array([1]), new Uint8Array([1, 0])));
1278
1204
  });
1279
1205
  await t2.step("a=[1,0], b=[1] (a longer with trailing zero)", () => {
1280
- const a2 = new Uint8Array([1, 0]);
1281
- const b2 = new Uint8Array([1]);
1282
- assertFalse(timingSafeEqual(a2, b2));
1206
+ assertFalse(timingSafeEqual(new Uint8Array([1, 0]), new Uint8Array([1])));
1283
1207
  });
1284
1208
  });
1285
1209
  });
@@ -1299,20 +1223,18 @@ test("signRequest() [rfc9421] error handling for invalid signature base creation
1299
1223
  assertExists(signedRequest.headers.get("Signature"));
1300
1224
  });
1301
1225
  test("verifyRequest() [rfc9421] error handling for invalid signature base creation", async () => {
1302
- const request = new Request("https://example.com/test", {
1226
+ assertEquals(await verifyRequest(new Request("https://example.com/test", {
1303
1227
  method: "GET",
1304
1228
  headers: {
1305
1229
  "Accept": "application/json",
1306
1230
  "Signature-Input": "sig1=(\"@unsupported\");alg=\"rsa-pss-sha256\";keyid=\"https://example.com/key2\";created=1234567890",
1307
1231
  "Signature": "sig1=:invalid_signature_data:"
1308
1232
  }
1309
- });
1310
- const result = await verifyRequest(request, {
1233
+ }), {
1311
1234
  spec: "rfc9421",
1312
1235
  documentLoader: mockDocumentLoader,
1313
1236
  contextLoader: mockDocumentLoader
1314
- });
1315
- assertEquals(result, null, "Verification should fail gracefully for malformed signature inputs");
1237
+ }), null, "Verification should fail gracefully for malformed signature inputs");
1316
1238
  });
1317
1239
  test("doubleKnock() regression test for TypeError: unusable bug #294", async () => {
1318
1240
  esm_default.spyGlobal();
@@ -1326,16 +1248,14 @@ test("doubleKnock() regression test for TypeError: unusable bug #294", async ()
1326
1248
  esm_default.post("https://example.com/final-destination", () => {
1327
1249
  return new Response("Success", { status: 200 });
1328
1250
  });
1329
- const request = new Request("https://example.com/inbox-retry-redirect", {
1251
+ assertEquals((await doubleKnock(new Request("https://example.com/inbox-retry-redirect", {
1330
1252
  method: "POST",
1331
1253
  body: "Test activity content",
1332
1254
  headers: { "Content-Type": "application/activity+json" }
1333
- });
1334
- const response = await doubleKnock(request, {
1255
+ }), {
1335
1256
  keyId: rsaPublicKey2.id,
1336
1257
  privateKey: rsaPrivateKey2
1337
- });
1338
- assertEquals(response.status, 200);
1258
+ })).status, 200);
1339
1259
  assertEquals(requestCount, 2, "Should make 2 requests before redirect");
1340
1260
  esm_default.hardReset();
1341
1261
  });
@@ -1350,16 +1270,14 @@ test("doubleKnock() regression test for redirect handling bug", async () => {
1350
1270
  esm_default.post("https://example.com/final-destination", () => {
1351
1271
  return new Response("Success", { status: 200 });
1352
1272
  });
1353
- const request = new Request("https://example.com/inbox-retry-redirect", {
1273
+ assertEquals((await doubleKnock(new Request("https://example.com/inbox-retry-redirect", {
1354
1274
  method: "POST",
1355
1275
  body: "Test activity content",
1356
1276
  headers: { "Content-Type": "application/activity+json" }
1357
- });
1358
- const response = await doubleKnock(request, {
1277
+ }), {
1359
1278
  keyId: rsaPublicKey2.id,
1360
1279
  privateKey: rsaPrivateKey2
1361
- });
1362
- assertEquals(response.status, 200);
1280
+ })).status, 200);
1363
1281
  esm_default.hardReset();
1364
1282
  });
1365
1283
  test("signRequest() and verifyRequest() cancellation", {
@@ -1405,22 +1323,19 @@ test("signRequest() and verifyRequest() cancellation", {
1405
1323
  esm_default.hardReset();
1406
1324
  });
1407
1325
  test("signRequest() with custom label", async () => {
1408
- const request = new Request("https://example.com/api", {
1326
+ const signed = await signRequest(new Request("https://example.com/api", {
1409
1327
  method: "POST",
1410
1328
  body: "test",
1411
1329
  headers: { "Content-Type": "text/plain" }
1412
- });
1413
- const signed = await signRequest(request, rsaPrivateKey2, new URL("https://example.com/key2"), {
1330
+ }), rsaPrivateKey2, new URL("https://example.com/key2"), {
1414
1331
  spec: "rfc9421",
1415
1332
  rfc9421: { label: "mysig" }
1416
1333
  });
1417
- const sigInput = signed.headers.get("Signature-Input");
1418
- assertStringIncludes(sigInput, "mysig=");
1419
- const sig = signed.headers.get("Signature");
1420
- assertStringIncludes(sig, "mysig=");
1334
+ assertStringIncludes(signed.headers.get("Signature-Input"), "mysig=");
1335
+ assertStringIncludes(signed.headers.get("Signature"), "mysig=");
1421
1336
  });
1422
1337
  test("signRequest() with custom components", async () => {
1423
- const request = new Request("https://example.com/api", {
1338
+ const sigInput = (await signRequest(new Request("https://example.com/api", {
1424
1339
  method: "POST",
1425
1340
  body: "test",
1426
1341
  headers: {
@@ -1428,8 +1343,7 @@ test("signRequest() with custom components", async () => {
1428
1343
  "Host": "example.com",
1429
1344
  "Date": "Tue, 05 Mar 2024 07:49:44 GMT"
1430
1345
  }
1431
- });
1432
- const signed = await signRequest(request, rsaPrivateKey2, new URL("https://example.com/key2"), {
1346
+ }), rsaPrivateKey2, new URL("https://example.com/key2"), {
1433
1347
  spec: "rfc9421",
1434
1348
  rfc9421: { components: [
1435
1349
  {
@@ -1445,29 +1359,26 @@ test("signRequest() with custom components", async () => {
1445
1359
  params: {}
1446
1360
  }
1447
1361
  ] }
1448
- });
1449
- const sigInput = signed.headers.get("Signature-Input");
1362
+ })).headers.get("Signature-Input");
1450
1363
  assertStringIncludes(sigInput, "\"@method\"");
1451
1364
  assertStringIncludes(sigInput, "\"@target-uri\"");
1452
1365
  assertStringIncludes(sigInput, "\"@authority\"");
1453
1366
  assertStringIncludes(sigInput, "\"content-digest\"");
1454
1367
  });
1455
1368
  test("signRequest() with nonce and tag", async () => {
1456
- const request = new Request("https://example.com/api", {
1369
+ const sigInput = (await signRequest(new Request("https://example.com/api", {
1457
1370
  method: "GET",
1458
1371
  headers: {
1459
1372
  "Host": "example.com",
1460
1373
  "Date": "Tue, 05 Mar 2024 07:49:44 GMT"
1461
1374
  }
1462
- });
1463
- const signed = await signRequest(request, rsaPrivateKey2, new URL("https://example.com/key2"), {
1375
+ }), rsaPrivateKey2, new URL("https://example.com/key2"), {
1464
1376
  spec: "rfc9421",
1465
1377
  rfc9421: {
1466
1378
  nonce: "test-nonce-123",
1467
1379
  tag: "app-v1"
1468
1380
  }
1469
- });
1470
- const sigInput = signed.headers.get("Signature-Input");
1381
+ })).headers.get("Signature-Input");
1471
1382
  assertStringIncludes(sigInput, "nonce=\"test-nonce-123\"");
1472
1383
  assertStringIncludes(sigInput, "tag=\"app-v1\"");
1473
1384
  });
@@ -1477,26 +1388,22 @@ test("formatRfc9421SignatureParameters() escapes nonce and tag", () => {
1477
1388
  keyId: new URL("https://example.com/key"),
1478
1389
  created: 1709626184
1479
1390
  };
1480
- const slashNonce = formatRfc9421SignatureParameters({
1391
+ assertStringIncludes(formatRfc9421SignatureParameters({
1481
1392
  ...commonParams,
1482
1393
  nonce: "x\\y"
1483
- });
1484
- assertStringIncludes(slashNonce, "nonce=\"x\\\\y\"");
1485
- const quoteNonce = formatRfc9421SignatureParameters({
1394
+ }), "nonce=\"x\\\\y\"");
1395
+ assertStringIncludes(formatRfc9421SignatureParameters({
1486
1396
  ...commonParams,
1487
1397
  nonce: "a\"b"
1488
- });
1489
- assertStringIncludes(quoteNonce, "nonce=\"a\\\"b\"");
1490
- const slashTag = formatRfc9421SignatureParameters({
1398
+ }), "nonce=\"a\\\"b\"");
1399
+ assertStringIncludes(formatRfc9421SignatureParameters({
1491
1400
  ...commonParams,
1492
1401
  tag: "x\\y"
1493
- });
1494
- assertStringIncludes(slashTag, "tag=\"x\\\\y\"");
1495
- const quoteTag = formatRfc9421SignatureParameters({
1402
+ }), "tag=\"x\\\\y\"");
1403
+ assertStringIncludes(formatRfc9421SignatureParameters({
1496
1404
  ...commonParams,
1497
1405
  tag: "a\"b"
1498
- });
1499
- assertStringIncludes(quoteTag, "tag=\"a\\\"b\"");
1406
+ }), "tag=\"a\\\"b\"");
1500
1407
  const mixed = formatRfc9421SignatureParameters({
1501
1408
  ...commonParams,
1502
1409
  nonce: "n\"o\\nce",
@@ -1506,12 +1413,11 @@ test("formatRfc9421SignatureParameters() escapes nonce and tag", () => {
1506
1413
  assertStringIncludes(mixed, "tag=\"t\\\"ag\\\\value\"");
1507
1414
  });
1508
1415
  test("signRequest() [rfc9421] accumulates multiple signatures when called sequentially", async () => {
1509
- const request = new Request("https://example.com/inbox", {
1416
+ const twiceSigned = await signRequest(await signRequest(new Request("https://example.com/inbox", {
1510
1417
  method: "POST",
1511
1418
  body: "Hello",
1512
1419
  headers: { "Content-Type": "text/plain" }
1513
- });
1514
- const onceSigned = await signRequest(request, rsaPrivateKey2, new URL("https://example.com/key2"), {
1420
+ }), rsaPrivateKey2, new URL("https://example.com/key2"), {
1515
1421
  spec: "rfc9421",
1516
1422
  rfc9421: {
1517
1423
  label: "sig1",
@@ -1523,8 +1429,7 @@ test("signRequest() [rfc9421] accumulates multiple signatures when called sequen
1523
1429
  params: {}
1524
1430
  }]
1525
1431
  }
1526
- });
1527
- const twiceSigned = await signRequest(onceSigned, rsaPrivateKey2, new URL("https://example.com/key2"), {
1432
+ }), rsaPrivateKey2, new URL("https://example.com/key2"), {
1528
1433
  spec: "rfc9421",
1529
1434
  rfc9421: {
1530
1435
  label: "sig2",
@@ -1551,20 +1456,17 @@ test("doubleKnock(): Accept-Signature challenge retry succeeds", async () => {
1551
1456
  status: 401,
1552
1457
  headers: { "Accept-Signature": "sig1=(\"@method\" \"@target-uri\" \"@authority\" \"content-digest\");created;nonce=\"challenge-nonce-1\"" }
1553
1458
  });
1554
- const sigInput = req.headers.get("Signature-Input") ?? "";
1555
- if (sigInput.includes("challenge-nonce-1")) return new Response("", { status: 202 });
1459
+ if ((req.headers.get("Signature-Input") ?? "").includes("challenge-nonce-1")) return new Response("", { status: 202 });
1556
1460
  return new Response("Bad", { status: 400 });
1557
1461
  });
1558
- const request = new Request("https://example.com/inbox-challenge-ok", {
1462
+ assertEquals((await doubleKnock(new Request("https://example.com/inbox-challenge-ok", {
1559
1463
  method: "POST",
1560
1464
  body: "Test message",
1561
1465
  headers: { "Content-Type": "text/plain" }
1562
- });
1563
- const response = await doubleKnock(request, {
1466
+ }), {
1564
1467
  keyId: rsaPublicKey2.id,
1565
1468
  privateKey: rsaPrivateKey2
1566
- });
1567
- assertEquals(response.status, 202);
1469
+ })).status, 202);
1568
1470
  assertEquals(requestCount, 2);
1569
1471
  esm_default.hardReset();
1570
1472
  });
@@ -1581,16 +1483,14 @@ test("doubleKnock(): unfulfillable Accept-Signature falls to legacy fallback", a
1581
1483
  if (req.headers.has("Signature") && !req.headers.has("Signature-Input")) return new Response("", { status: 202 });
1582
1484
  return new Response("Bad", { status: 400 });
1583
1485
  });
1584
- const request = new Request("https://example.com/inbox-unfulfillable", {
1486
+ assertEquals((await doubleKnock(new Request("https://example.com/inbox-unfulfillable", {
1585
1487
  method: "POST",
1586
1488
  body: "Test message",
1587
1489
  headers: { "Content-Type": "text/plain" }
1588
- });
1589
- const response = await doubleKnock(request, {
1490
+ }), {
1590
1491
  keyId: rsaPublicKey2.id,
1591
1492
  privateKey: rsaPrivateKey2
1592
- });
1593
- assertEquals(response.status, 202);
1493
+ })).status, 202);
1594
1494
  assertEquals(requestCount, 2);
1595
1495
  esm_default.hardReset();
1596
1496
  });
@@ -1604,16 +1504,14 @@ test("doubleKnock(): no Accept-Signature falls to legacy fallback", async () =>
1604
1504
  if (req.headers.has("Signature")) return new Response("", { status: 202 });
1605
1505
  return new Response("Bad", { status: 400 });
1606
1506
  });
1607
- const request = new Request("https://example.com/inbox-no-challenge", {
1507
+ assertEquals((await doubleKnock(new Request("https://example.com/inbox-no-challenge", {
1608
1508
  method: "POST",
1609
1509
  body: "Test message",
1610
1510
  headers: { "Content-Type": "text/plain" }
1611
- });
1612
- const response = await doubleKnock(request, {
1511
+ }), {
1613
1512
  keyId: rsaPublicKey2.id,
1614
1513
  privateKey: rsaPrivateKey2
1615
- });
1616
- assertEquals(response.status, 202);
1514
+ })).status, 202);
1617
1515
  assertEquals(requestCount, 2);
1618
1516
  esm_default.hardReset();
1619
1517
  });
@@ -1631,16 +1529,14 @@ test("doubleKnock(): challenge retry also fails → legacy fallback attempted",
1631
1529
  if (req.headers.has("Signature") && !req.headers.has("Signature-Input")) return new Response("", { status: 202 });
1632
1530
  return new Response("Bad", { status: 400 });
1633
1531
  });
1634
- const request = new Request("https://example.com/inbox-challenge-fails", {
1532
+ assertEquals((await doubleKnock(new Request("https://example.com/inbox-challenge-fails", {
1635
1533
  method: "POST",
1636
1534
  body: "Test message",
1637
1535
  headers: { "Content-Type": "text/plain" }
1638
- });
1639
- const response = await doubleKnock(request, {
1536
+ }), {
1640
1537
  keyId: rsaPublicKey2.id,
1641
1538
  privateKey: rsaPrivateKey2
1642
- });
1643
- assertEquals(response.status, 202);
1539
+ })).status, 202);
1644
1540
  assertEquals(requestCount, 3);
1645
1541
  esm_default.hardReset();
1646
1542
  });
@@ -1661,16 +1557,14 @@ test("doubleKnock(): challenge retry returns another challenge → not followed"
1661
1557
  if (req.headers.has("Signature") && !req.headers.has("Signature-Input")) return new Response("", { status: 202 });
1662
1558
  return new Response("Bad", { status: 400 });
1663
1559
  });
1664
- const request = new Request("https://example.com/inbox-challenge-loop", {
1560
+ assertEquals((await doubleKnock(new Request("https://example.com/inbox-challenge-loop", {
1665
1561
  method: "POST",
1666
1562
  body: "Test message",
1667
1563
  headers: { "Content-Type": "text/plain" }
1668
- });
1669
- const response = await doubleKnock(request, {
1564
+ }), {
1670
1565
  keyId: rsaPublicKey2.id,
1671
1566
  privateKey: rsaPrivateKey2
1672
- });
1673
- assertEquals(response.status, 202);
1567
+ })).status, 202);
1674
1568
  assertEquals(requestCount, 3);
1675
1569
  esm_default.hardReset();
1676
1570
  });
@@ -1687,16 +1581,14 @@ test("doubleKnock(): Accept-Signature with unsupported component falls to legacy
1687
1581
  if (req.headers.has("Signature") && !req.headers.has("Signature-Input")) return new Response("", { status: 202 });
1688
1582
  return new Response("Bad", { status: 400 });
1689
1583
  });
1690
- const request = new Request("https://example.com/inbox-bad-challenge", {
1584
+ assertEquals((await doubleKnock(new Request("https://example.com/inbox-bad-challenge", {
1691
1585
  method: "POST",
1692
1586
  body: "Test message",
1693
1587
  headers: { "Content-Type": "text/plain" }
1694
- });
1695
- const response = await doubleKnock(request, {
1588
+ }), {
1696
1589
  keyId: rsaPublicKey2.id,
1697
1590
  privateKey: rsaPrivateKey2
1698
- });
1699
- assertEquals(response.status, 202);
1591
+ })).status, 202);
1700
1592
  assertEquals(requestCount, 2);
1701
1593
  esm_default.hardReset();
1702
1594
  });
@@ -1713,16 +1605,14 @@ test("doubleKnock(): Accept-Signature with unsupported derived component falls t
1713
1605
  if (req.headers.has("Signature") && !req.headers.has("Signature-Input")) return new Response("", { status: 202 });
1714
1606
  return new Response("Bad", { status: 400 });
1715
1607
  });
1716
- const request = new Request("https://example.com/inbox-bad-derived", {
1608
+ assertEquals((await doubleKnock(new Request("https://example.com/inbox-bad-derived", {
1717
1609
  method: "POST",
1718
1610
  body: "Test message",
1719
1611
  headers: { "Content-Type": "text/plain" }
1720
- });
1721
- const response = await doubleKnock(request, {
1612
+ }), {
1722
1613
  keyId: rsaPublicKey2.id,
1723
1614
  privateKey: rsaPrivateKey2
1724
- });
1725
- assertEquals(response.status, 202);
1615
+ })).status, 202);
1726
1616
  assertEquals(requestCount, 2);
1727
1617
  esm_default.hardReset();
1728
1618
  });
@@ -1739,16 +1629,14 @@ test("doubleKnock(): Accept-Signature with multiple entries where first throws f
1739
1629
  if (req.headers.has("Signature-Input")) return new Response("", { status: 202 });
1740
1630
  return new Response("Bad", { status: 400 });
1741
1631
  });
1742
- const request = new Request("https://example.com/inbox-multi-challenge", {
1632
+ assertEquals((await doubleKnock(new Request("https://example.com/inbox-multi-challenge", {
1743
1633
  method: "POST",
1744
1634
  body: "Test message",
1745
1635
  headers: { "Content-Type": "text/plain" }
1746
- });
1747
- const response = await doubleKnock(request, {
1636
+ }), {
1748
1637
  keyId: rsaPublicKey2.id,
1749
1638
  privateKey: rsaPrivateKey2
1750
- });
1751
- assertEquals(response.status, 202);
1639
+ })).status, 202);
1752
1640
  assertEquals(requestCount, 2);
1753
1641
  esm_default.hardReset();
1754
1642
  });
@@ -1767,18 +1655,16 @@ test("doubleKnock(): Accept-Signature with multiple compatible entries fulfills
1767
1655
  if (sigInput.includes("sig1=") && sigInput.includes("sig2=") && sig.includes("sig1=") && sig.includes("sig2=")) return new Response("", { status: 202 });
1768
1656
  return new Response("Missing signatures", { status: 400 });
1769
1657
  });
1770
- const request = new Request("https://example.com/inbox-multi-compat", {
1658
+ assertEquals((await doubleKnock(new Request("https://example.com/inbox-multi-compat", {
1771
1659
  method: "POST",
1772
1660
  body: "Test message",
1773
1661
  headers: { "Content-Type": "text/plain" }
1774
- });
1775
- const response = await doubleKnock(request, {
1662
+ }), {
1776
1663
  keyId: rsaPublicKey2.id,
1777
1664
  privateKey: rsaPrivateKey2
1778
- });
1779
- assertEquals(response.status, 202);
1665
+ })).status, 202);
1780
1666
  assertEquals(requestCount, 2);
1781
1667
  esm_default.hardReset();
1782
1668
  });
1783
-
1784
- //#endregion
1669
+ //#endregion
1670
+ export {};