@bradford-tech/supabase-integrity-attest 0.3.2 → 0.4.1

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 (69) hide show
  1. package/esm/assertion.d.ts +5 -2
  2. package/esm/assertion.d.ts.map +1 -1
  3. package/esm/assertion.js +5 -2
  4. package/esm/attestation.d.ts +6 -1
  5. package/esm/attestation.d.ts.map +1 -1
  6. package/esm/attestation.js +6 -1
  7. package/esm/mod.d.ts +79 -3
  8. package/esm/mod.d.ts.map +1 -1
  9. package/esm/mod.js +79 -3
  10. package/esm/src/errors.d.ts +28 -3
  11. package/esm/src/errors.d.ts.map +1 -1
  12. package/esm/src/errors.js +25 -2
  13. package/esm/src/with-assertion.d.ts +41 -3
  14. package/esm/src/with-assertion.d.ts.map +1 -1
  15. package/esm/src/with-assertion.js +28 -4
  16. package/esm/src/with-attestation.d.ts +79 -0
  17. package/esm/src/with-attestation.d.ts.map +1 -0
  18. package/esm/src/with-attestation.js +135 -0
  19. package/package.json +4 -7
  20. package/esm/_dnt.test_polyfills.d.ts.map +0 -1
  21. package/esm/_dnt.test_shims.d.ts.map +0 -1
  22. package/esm/deps/jsr.io/@std/assert/1.0.19/almost_equals.d.ts.map +0 -1
  23. package/esm/deps/jsr.io/@std/assert/1.0.19/array_includes.d.ts.map +0 -1
  24. package/esm/deps/jsr.io/@std/assert/1.0.19/assert.d.ts.map +0 -1
  25. package/esm/deps/jsr.io/@std/assert/1.0.19/assertion_error.d.ts.map +0 -1
  26. package/esm/deps/jsr.io/@std/assert/1.0.19/equal.d.ts.map +0 -1
  27. package/esm/deps/jsr.io/@std/assert/1.0.19/equals.d.ts.map +0 -1
  28. package/esm/deps/jsr.io/@std/assert/1.0.19/exists.d.ts.map +0 -1
  29. package/esm/deps/jsr.io/@std/assert/1.0.19/fail.d.ts.map +0 -1
  30. package/esm/deps/jsr.io/@std/assert/1.0.19/false.d.ts.map +0 -1
  31. package/esm/deps/jsr.io/@std/assert/1.0.19/greater.d.ts.map +0 -1
  32. package/esm/deps/jsr.io/@std/assert/1.0.19/greater_or_equal.d.ts.map +0 -1
  33. package/esm/deps/jsr.io/@std/assert/1.0.19/instance_of.d.ts.map +0 -1
  34. package/esm/deps/jsr.io/@std/assert/1.0.19/is_error.d.ts.map +0 -1
  35. package/esm/deps/jsr.io/@std/assert/1.0.19/less.d.ts.map +0 -1
  36. package/esm/deps/jsr.io/@std/assert/1.0.19/less_or_equal.d.ts.map +0 -1
  37. package/esm/deps/jsr.io/@std/assert/1.0.19/match.d.ts.map +0 -1
  38. package/esm/deps/jsr.io/@std/assert/1.0.19/mod.d.ts.map +0 -1
  39. package/esm/deps/jsr.io/@std/assert/1.0.19/not_equals.d.ts.map +0 -1
  40. package/esm/deps/jsr.io/@std/assert/1.0.19/not_instance_of.d.ts.map +0 -1
  41. package/esm/deps/jsr.io/@std/assert/1.0.19/not_match.d.ts.map +0 -1
  42. package/esm/deps/jsr.io/@std/assert/1.0.19/not_strict_equals.d.ts.map +0 -1
  43. package/esm/deps/jsr.io/@std/assert/1.0.19/object_match.d.ts.map +0 -1
  44. package/esm/deps/jsr.io/@std/assert/1.0.19/rejects.d.ts.map +0 -1
  45. package/esm/deps/jsr.io/@std/assert/1.0.19/strict_equals.d.ts.map +0 -1
  46. package/esm/deps/jsr.io/@std/assert/1.0.19/string_includes.d.ts.map +0 -1
  47. package/esm/deps/jsr.io/@std/assert/1.0.19/throws.d.ts.map +0 -1
  48. package/esm/deps/jsr.io/@std/assert/1.0.19/unimplemented.d.ts.map +0 -1
  49. package/esm/deps/jsr.io/@std/assert/1.0.19/unreachable.d.ts.map +0 -1
  50. package/esm/deps/jsr.io/@std/internal/1.0.12/build_message.d.ts.map +0 -1
  51. package/esm/deps/jsr.io/@std/internal/1.0.12/diff.d.ts.map +0 -1
  52. package/esm/deps/jsr.io/@std/internal/1.0.12/diff_str.d.ts.map +0 -1
  53. package/esm/deps/jsr.io/@std/internal/1.0.12/format.d.ts.map +0 -1
  54. package/esm/deps/jsr.io/@std/internal/1.0.12/styles.d.ts.map +0 -1
  55. package/esm/deps/jsr.io/@std/internal/1.0.12/types.d.ts.map +0 -1
  56. package/esm/src/cose.d.ts.map +0 -1
  57. package/esm/tests/assertion-entry.test.d.ts.map +0 -1
  58. package/esm/tests/assertion.test.d.ts.map +0 -1
  59. package/esm/tests/attestation-entry.test.d.ts.map +0 -1
  60. package/esm/tests/attestation.test.d.ts.map +0 -1
  61. package/esm/tests/authdata.test.d.ts.map +0 -1
  62. package/esm/tests/certificate.test.d.ts.map +0 -1
  63. package/esm/tests/cose.test.d.ts.map +0 -1
  64. package/esm/tests/der.test.d.ts.map +0 -1
  65. package/esm/tests/errors.test.d.ts.map +0 -1
  66. package/esm/tests/fixtures/apple-attestation.d.ts.map +0 -1
  67. package/esm/tests/fixtures/generate-assertion.d.ts.map +0 -1
  68. package/esm/tests/utils.test.d.ts.map +0 -1
  69. package/esm/tests/with-assertion.test.d.ts.map +0 -1
@@ -3,7 +3,10 @@
3
3
  * `@noble/curves`, keeping the bundle minimal for assertion-only use cases.
4
4
  *
5
5
  * ```ts
6
- * import { verifyAssertion } from "@bradford-tech/supabase-integrity-attest/assertion";
6
+ * import {
7
+ * verifyAssertion,
8
+ * withAssertion,
9
+ * } from "@bradford-tech/supabase-integrity-attest/assertion";
7
10
  *
8
11
  * const { signCount } = await verifyAssertion(
9
12
  * { appId: "TEAMID.com.example.app" },
@@ -21,5 +24,5 @@ export type { AppInfo, AssertionResult } from "./src/assertion.js";
21
24
  export { AssertionError, AssertionErrorCode } from "./src/errors.js";
22
25
  export { withAssertion } from "./src/with-assertion.js";
23
26
  export { DEFAULT_ASSERTION_HEADER, DEFAULT_DEVICE_ID_HEADER, } from "./src/with-assertion.js";
24
- export type { AssertionContext, DeviceKey, ExtractAssertionFn, WithAssertionOptions, } from "./src/with-assertion.js";
27
+ export type { AssertionContext, AssertionTimings, DeviceKey, ExtractAssertionFn, WithAssertionOptions, } from "./src/with-assertion.js";
25
28
  //# sourceMappingURL=assertion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"assertion.d.ts","sourceRoot":"","sources":["../src/assertion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EACL,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"assertion.d.ts","sourceRoot":"","sources":["../src/assertion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EACL,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC"}
package/esm/assertion.js CHANGED
@@ -3,7 +3,10 @@
3
3
  * `@noble/curves`, keeping the bundle minimal for assertion-only use cases.
4
4
  *
5
5
  * ```ts
6
- * import { verifyAssertion } from "@bradford-tech/supabase-integrity-attest/assertion";
6
+ * import {
7
+ * verifyAssertion,
8
+ * withAssertion,
9
+ * } from "@bradford-tech/supabase-integrity-attest/assertion";
7
10
  *
8
11
  * const { signCount } = await verifyAssertion(
9
12
  * { appId: "TEAMID.com.example.app" },
@@ -18,6 +21,6 @@
18
21
  */
19
22
  export { verifyAssertion } from "./src/assertion.js";
20
23
  export { AssertionError, AssertionErrorCode } from "./src/errors.js";
21
- // withAssertion wrapper
24
+ // withAssertion middleware
22
25
  export { withAssertion } from "./src/with-assertion.js";
23
26
  export { DEFAULT_ASSERTION_HEADER, DEFAULT_DEVICE_ID_HEADER, } from "./src/with-assertion.js";
@@ -3,7 +3,10 @@
3
3
  * dependencies (`asn1js`, `@noble/curves`).
4
4
  *
5
5
  * ```ts
6
- * import { verifyAttestation } from "@bradford-tech/supabase-integrity-attest/attestation";
6
+ * import {
7
+ * verifyAttestation,
8
+ * withAttestation,
9
+ * } from "@bradford-tech/supabase-integrity-attest/attestation";
7
10
  *
8
11
  * const { publicKeyPem } = await verifyAttestation(
9
12
  * { appId: "TEAMID.com.example.app" },
@@ -18,4 +21,6 @@
18
21
  export { verifyAttestation } from "./src/attestation.js";
19
22
  export type { AppInfo, AttestationResult, VerifyAttestationOptions, } from "./src/attestation.js";
20
23
  export { AttestationError, AttestationErrorCode } from "./src/errors.js";
24
+ export { withAttestation } from "./src/with-attestation.js";
25
+ export type { AttestationContext, AttestationTimings, ExtractAttestationFn, WithAttestationOptions, } from "./src/with-attestation.js";
21
26
  //# sourceMappingURL=attestation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"attestation.d.ts","sourceRoot":"","sources":["../src/attestation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"attestation.d.ts","sourceRoot":"","sources":["../src/attestation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAGzE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,2BAA2B,CAAC"}
@@ -3,7 +3,10 @@
3
3
  * dependencies (`asn1js`, `@noble/curves`).
4
4
  *
5
5
  * ```ts
6
- * import { verifyAttestation } from "@bradford-tech/supabase-integrity-attest/attestation";
6
+ * import {
7
+ * verifyAttestation,
8
+ * withAttestation,
9
+ * } from "@bradford-tech/supabase-integrity-attest/attestation";
7
10
  *
8
11
  * const { publicKeyPem } = await verifyAttestation(
9
12
  * { appId: "TEAMID.com.example.app" },
@@ -17,3 +20,5 @@
17
20
  */
18
21
  export { verifyAttestation } from "./src/attestation.js";
19
22
  export { AttestationError, AttestationErrorCode } from "./src/errors.js";
23
+ // withAttestation middleware
24
+ export { withAttestation } from "./src/with-attestation.js";
package/esm/mod.d.ts CHANGED
@@ -1,17 +1,91 @@
1
1
  /**
2
2
  * Verify Apple App Attest attestations and assertions using WebCrypto.
3
3
  *
4
+ * This library implements Apple's full
5
+ * [App Attest](https://developer.apple.com/documentation/devicecheck/establishing-your-app-s-integrity)
6
+ * server-side verification — CBOR decoding, X.509 certificate chain
7
+ * validation, nonce verification, ECDSA signature checks — using only
8
+ * WebCrypto APIs so it runs in Supabase Edge Functions, Deno Deploy,
9
+ * and other edge runtimes with no native dependencies.
10
+ *
11
+ * ## Attestation
12
+ *
13
+ * Verify a new device and extract its public key:
14
+ *
4
15
  * ```ts
5
- * import { verifyAttestation, verifyAssertion } from "@bradford-tech/supabase-integrity-attest";
16
+ * import { verifyAttestation } from "@bradford-tech/supabase-integrity-attest";
6
17
  *
7
- * const { publicKeyPem } = await verifyAttestation(
18
+ * const { publicKeyPem, receipt, signCount } = await verifyAttestation(
8
19
  * { appId: "TEAMID.com.example.app" },
9
20
  * keyId,
10
21
  * challenge,
11
22
  * attestation,
12
23
  * );
24
+ * // Store publicKeyPem and signCount for future assertion verification
25
+ * ```
26
+ *
27
+ * ## Assertion
28
+ *
29
+ * Verify ongoing requests from an already-attested device:
30
+ *
31
+ * ```ts
32
+ * import { verifyAssertion } from "@bradford-tech/supabase-integrity-attest";
33
+ *
34
+ * const { signCount } = await verifyAssertion(
35
+ * { appId: "TEAMID.com.example.app" },
36
+ * assertion,
37
+ * clientData,
38
+ * publicKeyPem,
39
+ * previousSignCount,
40
+ * );
41
+ * // Persist the updated signCount
42
+ * ```
43
+ *
44
+ * ## Middleware
45
+ *
46
+ * Use the {@linkcode withAttestation} and {@linkcode withAssertion}
47
+ * wrappers for automatic verification, callback-driven storage, and
48
+ * typed error handling:
49
+ *
50
+ * ```ts
51
+ * import {
52
+ * withAttestation,
53
+ * withAssertion,
54
+ * } from "@bradford-tech/supabase-integrity-attest";
55
+ *
56
+ * const attestHandler = withAttestation(
57
+ * {
58
+ * appId: "TEAMID.com.example.app",
59
+ * consumeChallenge,
60
+ * storeDeviceKey,
61
+ * },
62
+ * (_req, ctx) =>
63
+ * Response.json({ ok: true, deviceId: ctx.deviceId }),
64
+ * );
65
+ *
66
+ * const protectedHandler = withAssertion(
67
+ * {
68
+ * appId: "TEAMID.com.example.app",
69
+ * getDeviceKey,
70
+ * commitSignCount,
71
+ * },
72
+ * (_req, ctx) =>
73
+ * Response.json({ hello: ctx.deviceId, counter: ctx.signCount }),
74
+ * );
13
75
  * ```
14
76
  *
77
+ * ## Subpath imports
78
+ *
79
+ * For smaller bundles, import only what you need:
80
+ *
81
+ * - `@bradford-tech/supabase-integrity-attest/attestation` — attestation
82
+ * (`verifyAttestation`, `withAttestation`). Full crypto deps.
83
+ * - `@bradford-tech/supabase-integrity-attest/assertion` — assertion
84
+ * (`verifyAssertion`, `withAssertion`). Excludes `asn1js` and
85
+ * `@noble/curves` to keep the bundle minimal.
86
+ *
87
+ * Full documentation: {@link https://integrity-attest.bradford.tech}
88
+ *
15
89
  * @module
16
90
  */
17
91
  export type { AppInfo, AttestationResult, VerifyAttestationOptions, } from "./src/attestation.js";
@@ -21,5 +95,7 @@ export { verifyAssertion } from "./src/assertion.js";
21
95
  export { AssertionError, AssertionErrorCode, AttestationError, AttestationErrorCode, } from "./src/errors.js";
22
96
  export { withAssertion } from "./src/with-assertion.js";
23
97
  export { DEFAULT_ASSERTION_HEADER, DEFAULT_DEVICE_ID_HEADER, } from "./src/with-assertion.js";
24
- export type { AssertionContext, DeviceKey, ExtractAssertionFn, WithAssertionOptions, } from "./src/with-assertion.js";
98
+ export type { AssertionContext, AssertionTimings, DeviceKey, ExtractAssertionFn, WithAssertionOptions, } from "./src/with-assertion.js";
99
+ export { withAttestation } from "./src/with-attestation.js";
100
+ export type { AttestationContext, AttestationTimings, ExtractAttestationFn, WithAttestationOptions, } from "./src/with-attestation.js";
25
101
  //# sourceMappingURL=mod.d.ts.map
package/esm/mod.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EACL,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyFG;AAEH,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EACL,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,2BAA2B,CAAC"}
package/esm/mod.js CHANGED
@@ -1,22 +1,98 @@
1
1
  /**
2
2
  * Verify Apple App Attest attestations and assertions using WebCrypto.
3
3
  *
4
+ * This library implements Apple's full
5
+ * [App Attest](https://developer.apple.com/documentation/devicecheck/establishing-your-app-s-integrity)
6
+ * server-side verification — CBOR decoding, X.509 certificate chain
7
+ * validation, nonce verification, ECDSA signature checks — using only
8
+ * WebCrypto APIs so it runs in Supabase Edge Functions, Deno Deploy,
9
+ * and other edge runtimes with no native dependencies.
10
+ *
11
+ * ## Attestation
12
+ *
13
+ * Verify a new device and extract its public key:
14
+ *
4
15
  * ```ts
5
- * import { verifyAttestation, verifyAssertion } from "@bradford-tech/supabase-integrity-attest";
16
+ * import { verifyAttestation } from "@bradford-tech/supabase-integrity-attest";
6
17
  *
7
- * const { publicKeyPem } = await verifyAttestation(
18
+ * const { publicKeyPem, receipt, signCount } = await verifyAttestation(
8
19
  * { appId: "TEAMID.com.example.app" },
9
20
  * keyId,
10
21
  * challenge,
11
22
  * attestation,
12
23
  * );
24
+ * // Store publicKeyPem and signCount for future assertion verification
25
+ * ```
26
+ *
27
+ * ## Assertion
28
+ *
29
+ * Verify ongoing requests from an already-attested device:
30
+ *
31
+ * ```ts
32
+ * import { verifyAssertion } from "@bradford-tech/supabase-integrity-attest";
33
+ *
34
+ * const { signCount } = await verifyAssertion(
35
+ * { appId: "TEAMID.com.example.app" },
36
+ * assertion,
37
+ * clientData,
38
+ * publicKeyPem,
39
+ * previousSignCount,
40
+ * );
41
+ * // Persist the updated signCount
42
+ * ```
43
+ *
44
+ * ## Middleware
45
+ *
46
+ * Use the {@linkcode withAttestation} and {@linkcode withAssertion}
47
+ * wrappers for automatic verification, callback-driven storage, and
48
+ * typed error handling:
49
+ *
50
+ * ```ts
51
+ * import {
52
+ * withAttestation,
53
+ * withAssertion,
54
+ * } from "@bradford-tech/supabase-integrity-attest";
55
+ *
56
+ * const attestHandler = withAttestation(
57
+ * {
58
+ * appId: "TEAMID.com.example.app",
59
+ * consumeChallenge,
60
+ * storeDeviceKey,
61
+ * },
62
+ * (_req, ctx) =>
63
+ * Response.json({ ok: true, deviceId: ctx.deviceId }),
64
+ * );
65
+ *
66
+ * const protectedHandler = withAssertion(
67
+ * {
68
+ * appId: "TEAMID.com.example.app",
69
+ * getDeviceKey,
70
+ * commitSignCount,
71
+ * },
72
+ * (_req, ctx) =>
73
+ * Response.json({ hello: ctx.deviceId, counter: ctx.signCount }),
74
+ * );
13
75
  * ```
14
76
  *
77
+ * ## Subpath imports
78
+ *
79
+ * For smaller bundles, import only what you need:
80
+ *
81
+ * - `@bradford-tech/supabase-integrity-attest/attestation` — attestation
82
+ * (`verifyAttestation`, `withAttestation`). Full crypto deps.
83
+ * - `@bradford-tech/supabase-integrity-attest/assertion` — assertion
84
+ * (`verifyAssertion`, `withAssertion`). Excludes `asn1js` and
85
+ * `@noble/curves` to keep the bundle minimal.
86
+ *
87
+ * Full documentation: {@link https://integrity-attest.bradford.tech}
88
+ *
15
89
  * @module
16
90
  */
17
91
  export { verifyAttestation } from "./src/attestation.js";
18
92
  export { verifyAssertion } from "./src/assertion.js";
19
93
  export { AssertionError, AssertionErrorCode, AttestationError, AttestationErrorCode, } from "./src/errors.js";
20
- // withAssertion wrapper
94
+ // withAssertion middleware
21
95
  export { withAssertion } from "./src/with-assertion.js";
22
96
  export { DEFAULT_ASSERTION_HEADER, DEFAULT_DEVICE_ID_HEADER, } from "./src/with-assertion.js";
97
+ // withAttestation middleware
98
+ export { withAttestation } from "./src/with-attestation.js";
@@ -13,16 +13,32 @@ export declare enum AttestationErrorCode {
13
13
  /** Sign count is not zero (required for attestation). */
14
14
  INVALID_COUNTER = "INVALID_COUNTER",
15
15
  /** AAGUID does not match the expected environment (production/development). */
16
- INVALID_AAGUID = "INVALID_AAGUID"
16
+ INVALID_AAGUID = "INVALID_AAGUID",
17
+ /**
18
+ * The `consumeChallenge` callback returned `false`, meaning the challenge
19
+ * was missing, expired, or already consumed. Used by {@linkcode withAttestation}.
20
+ */
21
+ CHALLENGE_INVALID = "CHALLENGE_INVALID",
22
+ /**
23
+ * An internal or storage callback error occurred (used by
24
+ * {@linkcode withAttestation}). The original error is attached via
25
+ * `Error.cause` and is deliberately NOT reflected in the HTTP response
26
+ * body to avoid leaking database schema or driver diagnostics.
27
+ */
28
+ INTERNAL_ERROR = "INTERNAL_ERROR"
17
29
  }
18
30
  /** Thrown when attestation verification fails. */
19
31
  export declare class AttestationError extends Error {
20
32
  /** Machine-readable error code. */
21
33
  readonly code: AttestationErrorCode;
34
+ /** Discriminant for `instanceof` checks in catch blocks. Always `"AttestationError"`. */
22
35
  readonly name = "AttestationError";
36
+ /** Create an AttestationError with a machine-readable code and human-readable message. */
23
37
  constructor(
24
38
  /** Machine-readable error code. */
25
- code: AttestationErrorCode, message: string);
39
+ code: AttestationErrorCode, message: string, options?: {
40
+ cause?: unknown;
41
+ });
26
42
  }
27
43
  /** Error codes returned by {@linkcode AssertionError}. */
28
44
  export declare enum AssertionErrorCode {
@@ -37,13 +53,22 @@ export declare enum AssertionErrorCode {
37
53
  /** No device key found for the given device ID (used by {@linkcode withAssertion}). */
38
54
  DEVICE_NOT_FOUND = "DEVICE_NOT_FOUND",
39
55
  /** An internal or storage callback error occurred (used by {@linkcode withAssertion}). */
40
- INTERNAL_ERROR = "INTERNAL_ERROR"
56
+ INTERNAL_ERROR = "INTERNAL_ERROR",
57
+ /**
58
+ * The `commitSignCount` callback returned `false`, meaning another
59
+ * concurrent request already advanced the stored counter past this value.
60
+ * Indicates an expected race under concurrent load, not a client bug.
61
+ * Used by {@linkcode withAssertion}.
62
+ */
63
+ SIGN_COUNT_STALE = "SIGN_COUNT_STALE"
41
64
  }
42
65
  /** Thrown when assertion verification fails. */
43
66
  export declare class AssertionError extends Error {
44
67
  /** Machine-readable error code. */
45
68
  readonly code: AssertionErrorCode;
69
+ /** Discriminant for `instanceof` checks in catch blocks. Always `"AssertionError"`. */
46
70
  readonly name = "AssertionError";
71
+ /** Create an AssertionError with a machine-readable code and human-readable message. */
47
72
  constructor(
48
73
  /** Machine-readable error code. */
49
74
  code: AssertionErrorCode, message: string, options?: {
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/src/errors.ts"],"names":[],"mappings":"AAEA,4DAA4D;AAC5D,oBAAY,oBAAoB;IAC9B,qDAAqD;IACrD,cAAc,mBAAmB;IACjC,mDAAmD;IACnD,yBAAyB,8BAA8B;IACvD,uEAAuE;IACvE,cAAc,mBAAmB;IACjC,uDAAuD;IACvD,cAAc,mBAAmB;IACjC,0DAA0D;IAC1D,eAAe,oBAAoB;IACnC,yDAAyD;IACzD,eAAe,oBAAoB;IACnC,+EAA+E;IAC/E,cAAc,mBAAmB;CAClC;AAED,kDAAkD;AAClD,qBAAa,gBAAiB,SAAQ,KAAK;IAGvC,mCAAmC;aACnB,IAAI,EAAE,oBAAoB;IAH5C,SAAkB,IAAI,sBAAsB;;IAE1C,mCAAmC;IACnB,IAAI,EAAE,oBAAoB,EAC1C,OAAO,EAAE,MAAM;CAIlB;AAED,0DAA0D;AAC1D,oBAAY,kBAAkB;IAC5B,qDAAqD;IACrD,cAAc,mBAAmB;IACjC,uDAAuD;IACvD,cAAc,mBAAmB;IACjC,mEAAmE;IACnE,uBAAuB,4BAA4B;IACnD,2CAA2C;IAC3C,iBAAiB,sBAAsB;IACvC,uFAAuF;IACvF,gBAAgB,qBAAqB;IACrC,0FAA0F;IAC1F,cAAc,mBAAmB;CAClC;AAED,gDAAgD;AAChD,qBAAa,cAAe,SAAQ,KAAK;IAGrC,mCAAmC;aACnB,IAAI,EAAE,kBAAkB;IAH1C,SAAkB,IAAI,oBAAoB;;IAExC,mCAAmC;IACnB,IAAI,EAAE,kBAAkB,EACxC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAIhC"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/src/errors.ts"],"names":[],"mappings":"AAEA,4DAA4D;AAC5D,oBAAY,oBAAoB;IAC9B,qDAAqD;IACrD,cAAc,mBAAmB;IACjC,mDAAmD;IACnD,yBAAyB,8BAA8B;IACvD,uEAAuE;IACvE,cAAc,mBAAmB;IACjC,uDAAuD;IACvD,cAAc,mBAAmB;IACjC,0DAA0D;IAC1D,eAAe,oBAAoB;IACnC,yDAAyD;IACzD,eAAe,oBAAoB;IACnC,+EAA+E;IAC/E,cAAc,mBAAmB;IACjC;;;OAGG;IACH,iBAAiB,sBAAsB;IACvC;;;;;OAKG;IACH,cAAc,mBAAmB;CAClC;AAED,kDAAkD;AAClD,qBAAa,gBAAiB,SAAQ,KAAK;IAKvC,mCAAmC;aACnB,IAAI,EAAE,oBAAoB;IAL5C,yFAAyF;IACzF,SAAkB,IAAI,sBAAsB;IAC5C,0FAA0F;;IAExF,mCAAmC;IACnB,IAAI,EAAE,oBAAoB,EAC1C,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAIhC;AAED,0DAA0D;AAC1D,oBAAY,kBAAkB;IAC5B,qDAAqD;IACrD,cAAc,mBAAmB;IACjC,uDAAuD;IACvD,cAAc,mBAAmB;IACjC,mEAAmE;IACnE,uBAAuB,4BAA4B;IACnD,2CAA2C;IAC3C,iBAAiB,sBAAsB;IACvC,uFAAuF;IACvF,gBAAgB,qBAAqB;IACrC,0FAA0F;IAC1F,cAAc,mBAAmB;IACjC;;;;;OAKG;IACH,gBAAgB,qBAAqB;CACtC;AAED,gDAAgD;AAChD,qBAAa,cAAe,SAAQ,KAAK;IAKrC,mCAAmC;aACnB,IAAI,EAAE,kBAAkB;IAL1C,uFAAuF;IACvF,SAAkB,IAAI,oBAAoB;IAC1C,wFAAwF;;IAEtF,mCAAmC;IACnB,IAAI,EAAE,kBAAkB,EACxC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAIhC"}
package/esm/src/errors.js CHANGED
@@ -16,19 +16,33 @@ export var AttestationErrorCode;
16
16
  AttestationErrorCode["INVALID_COUNTER"] = "INVALID_COUNTER";
17
17
  /** AAGUID does not match the expected environment (production/development). */
18
18
  AttestationErrorCode["INVALID_AAGUID"] = "INVALID_AAGUID";
19
+ /**
20
+ * The `consumeChallenge` callback returned `false`, meaning the challenge
21
+ * was missing, expired, or already consumed. Used by {@linkcode withAttestation}.
22
+ */
23
+ AttestationErrorCode["CHALLENGE_INVALID"] = "CHALLENGE_INVALID";
24
+ /**
25
+ * An internal or storage callback error occurred (used by
26
+ * {@linkcode withAttestation}). The original error is attached via
27
+ * `Error.cause` and is deliberately NOT reflected in the HTTP response
28
+ * body to avoid leaking database schema or driver diagnostics.
29
+ */
30
+ AttestationErrorCode["INTERNAL_ERROR"] = "INTERNAL_ERROR";
19
31
  })(AttestationErrorCode || (AttestationErrorCode = {}));
20
32
  /** Thrown when attestation verification fails. */
21
33
  export class AttestationError extends Error {
34
+ /** Create an AttestationError with a machine-readable code and human-readable message. */
22
35
  constructor(
23
36
  /** Machine-readable error code. */
24
- code, message) {
25
- super(message);
37
+ code, message, options) {
38
+ super(message, options);
26
39
  Object.defineProperty(this, "code", {
27
40
  enumerable: true,
28
41
  configurable: true,
29
42
  writable: true,
30
43
  value: code
31
44
  });
45
+ /** Discriminant for `instanceof` checks in catch blocks. Always `"AttestationError"`. */
32
46
  Object.defineProperty(this, "name", {
33
47
  enumerable: true,
34
48
  configurable: true,
@@ -52,9 +66,17 @@ export var AssertionErrorCode;
52
66
  AssertionErrorCode["DEVICE_NOT_FOUND"] = "DEVICE_NOT_FOUND";
53
67
  /** An internal or storage callback error occurred (used by {@linkcode withAssertion}). */
54
68
  AssertionErrorCode["INTERNAL_ERROR"] = "INTERNAL_ERROR";
69
+ /**
70
+ * The `commitSignCount` callback returned `false`, meaning another
71
+ * concurrent request already advanced the stored counter past this value.
72
+ * Indicates an expected race under concurrent load, not a client bug.
73
+ * Used by {@linkcode withAssertion}.
74
+ */
75
+ AssertionErrorCode["SIGN_COUNT_STALE"] = "SIGN_COUNT_STALE";
55
76
  })(AssertionErrorCode || (AssertionErrorCode = {}));
56
77
  /** Thrown when assertion verification fails. */
57
78
  export class AssertionError extends Error {
79
+ /** Create an AssertionError with a machine-readable code and human-readable message. */
58
80
  constructor(
59
81
  /** Machine-readable error code. */
60
82
  code, message, options) {
@@ -65,6 +87,7 @@ export class AssertionError extends Error {
65
87
  writable: true,
66
88
  value: code
67
89
  });
90
+ /** Discriminant for `instanceof` checks in catch blocks. Always `"AssertionError"`. */
68
91
  Object.defineProperty(this, "name", {
69
92
  enumerable: true,
70
93
  configurable: true,
@@ -10,6 +10,21 @@ export type DeviceKey = {
10
10
  /** Last verified sign count for this device. */
11
11
  signCount: number;
12
12
  };
13
+ /**
14
+ * Library-internal timing spans for an assertion verification, in
15
+ * milliseconds. Exposed on {@linkcode AssertionContext.timings} so the
16
+ * wrapped handler can emit them as part of its own Server-Timing response.
17
+ */
18
+ export type AssertionTimings = {
19
+ /** Parse request headers and read raw body bytes. */
20
+ extractMs: number;
21
+ /** `getDeviceKey` callback wall-clock duration. */
22
+ getDeviceKeyMs: number;
23
+ /** Cryptographic verification (CBOR decode, ECDSA verify, counter check). */
24
+ verifyMs: number;
25
+ /** `commitSignCount` callback wall-clock duration. */
26
+ commitMs: number;
27
+ };
13
28
  /** Context passed to the inner handler after successful assertion verification. */
14
29
  export type AssertionContext = {
15
30
  /** Device identifier from the request. */
@@ -18,6 +33,8 @@ export type AssertionContext = {
18
33
  signCount: number;
19
34
  /** Raw request body bytes (the client data that was signed). */
20
35
  rawBody: Uint8Array;
36
+ /** Library-internal timings, ready to merge into Server-Timing. */
37
+ timings: AssertionTimings;
21
38
  };
22
39
  /** Custom function to extract assertion data from an incoming request. */
23
40
  export type ExtractAssertionFn = (req: Request) => Promise<{
@@ -33,8 +50,24 @@ export type WithAssertionOptions = {
33
50
  developmentEnv?: boolean;
34
51
  /** Retrieve the stored device key for a given device ID. Return `null` if not found. */
35
52
  getDeviceKey: (deviceId: string) => Promise<DeviceKey | null>;
36
- /** Persist the new sign count after successful verification. */
37
- updateSignCount: (deviceId: string, newSignCount: number) => Promise<void>;
53
+ /**
54
+ * Atomically advance the stored sign count. MUST be implemented as a
55
+ * compare-and-swap: only update if the currently stored value is strictly
56
+ * less than `newSignCount`. Returns `true` if the row was advanced,
57
+ * `false` if another concurrent request already advanced past this value.
58
+ *
59
+ * Recommended SQL pattern against Postgres:
60
+ *
61
+ * ```sql
62
+ * UPDATE app_attest_devices
63
+ * SET sign_count = $1, last_seen_at = now()
64
+ * WHERE device_id = $2 AND sign_count < $1
65
+ * ```
66
+ *
67
+ * Return `rowCount > 0`. The library converts `false` into
68
+ * `AssertionError(SIGN_COUNT_STALE)`.
69
+ */
70
+ commitSignCount: (deviceId: string, newSignCount: number) => Promise<boolean>;
38
71
  /** Override the default header-based assertion extraction. */
39
72
  extractAssertion?: ExtractAssertionFn;
40
73
  /** Custom error response handler. Defaults to JSON error responses. */
@@ -44,8 +77,13 @@ export type WithAssertionOptions = {
44
77
  * Request handler middleware that verifies App Attest assertions.
45
78
  *
46
79
  * Wraps a handler function with automatic assertion verification,
47
- * device key lookup, and sign count management. Returns a new handler
80
+ * device key lookup, and atomic sign-count commit. Returns a new handler
48
81
  * that rejects unauthenticated requests with appropriate HTTP error responses.
82
+ *
83
+ * The `commitSignCount` callback MUST implement compare-and-swap semantics
84
+ * (see {@linkcode WithAssertionOptions.commitSignCount}) — a non-atomic
85
+ * unconditional write will silently corrupt replay protection under
86
+ * concurrent load.
49
87
  */
50
88
  export declare function withAssertion(options: WithAssertionOptions, handler: (req: Request, context: AssertionContext) => Response | Promise<Response>): (req: Request) => Promise<Response>;
51
89
  //# sourceMappingURL=with-assertion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"with-assertion.d.ts","sourceRoot":"","sources":["../../src/src/with-assertion.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAsB,MAAM,aAAa,CAAC;AAEjE,iEAAiE;AACjE,eAAO,MAAM,wBAAwB,2BAA2B,CAAC;AACjE,0DAA0D;AAC1D,eAAO,MAAM,wBAAwB,2BAA2B,CAAC;AAEjE,0EAA0E;AAC1E,MAAM,MAAM,SAAS,GAAG;IACtB,2DAA2D;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,mFAAmF;AACnF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,OAAO,EAAE,UAAU,CAAC;CACrB,CAAC;AAEF,0EAA0E;AAC1E,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC,CAAC;AAEH,kEAAkE;AAClE,MAAM,MAAM,oBAAoB,GAAG;IACjC,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wFAAwF;IACxF,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC9D,gEAAgE;IAChE,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,uEAAuE;IACvE,OAAO,CAAC,EAAE,CACR,KAAK,EAAE,cAAc,EACrB,GAAG,EAAE,OAAO,KACT,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CACnC,CAAC;AAmCF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE,CACP,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,gBAAgB,KACtB,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,GAChC,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAuErC"}
1
+ {"version":3,"file":"with-assertion.d.ts","sourceRoot":"","sources":["../../src/src/with-assertion.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAsB,MAAM,aAAa,CAAC;AAEjE,iEAAiE;AACjE,eAAO,MAAM,wBAAwB,2BAA2B,CAAC;AACjE,0DAA0D;AAC1D,eAAO,MAAM,wBAAwB,2BAA2B,CAAC;AAEjE,0EAA0E;AAC1E,MAAM,MAAM,SAAS,GAAG;IACtB,2DAA2D;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,cAAc,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,mFAAmF;AACnF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,OAAO,EAAE,UAAU,CAAC;IACpB,mEAAmE;IACnE,OAAO,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF,0EAA0E;AAC1E,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC,CAAC;AAEH,kEAAkE;AAClE,MAAM,MAAM,oBAAoB,GAAG;IACjC,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wFAAwF;IACxF,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC9D;;;;;;;;;;;;;;;;OAgBG;IACH,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9E,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,uEAAuE;IACvE,OAAO,CAAC,EAAE,CACR,KAAK,EAAE,cAAc,EACrB,GAAG,EAAE,OAAO,KACT,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CACnC,CAAC;AAmCF;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE,CACP,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,gBAAgB,KACtB,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,GAChC,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CA+FrC"}
@@ -26,8 +26,13 @@ function defaultErrorResponse(error) {
26
26
  * Request handler middleware that verifies App Attest assertions.
27
27
  *
28
28
  * Wraps a handler function with automatic assertion verification,
29
- * device key lookup, and sign count management. Returns a new handler
29
+ * device key lookup, and atomic sign-count commit. Returns a new handler
30
30
  * that rejects unauthenticated requests with appropriate HTTP error responses.
31
+ *
32
+ * The `commitSignCount` callback MUST implement compare-and-swap semantics
33
+ * (see {@linkcode WithAssertionOptions.commitSignCount}) — a non-atomic
34
+ * unconditional write will silently corrupt replay protection under
35
+ * concurrent load.
31
36
  */
32
37
  export function withAssertion(options, handler) {
33
38
  const appInfo = {
@@ -39,11 +44,20 @@ export function withAssertion(options, handler) {
39
44
  let deviceId;
40
45
  let clientData;
41
46
  let newSignCount;
42
- // Steps 1-4: extract, verify, update sign count
47
+ const timings = {
48
+ extractMs: 0,
49
+ getDeviceKeyMs: 0,
50
+ verifyMs: 0,
51
+ commitMs: 0,
52
+ };
53
+ // Steps 1-4: extract, verify, commit sign count
43
54
  try {
55
+ const extractStart = performance.now();
44
56
  const extracted = await extract(req);
57
+ timings.extractMs = performance.now() - extractStart;
45
58
  deviceId = extracted.deviceId;
46
59
  clientData = extracted.clientData;
60
+ const getKeyStart = performance.now();
47
61
  let deviceKey;
48
62
  try {
49
63
  deviceKey = await options.getDeviceKey(deviceId);
@@ -51,15 +65,24 @@ export function withAssertion(options, handler) {
51
65
  catch (err) {
52
66
  throw new AssertionError(AssertionErrorCode.INTERNAL_ERROR, "Storage callback failed", { cause: err });
53
67
  }
68
+ timings.getDeviceKeyMs = performance.now() - getKeyStart;
54
69
  if (!deviceKey) {
55
70
  throw new AssertionError(AssertionErrorCode.DEVICE_NOT_FOUND, "Device not found");
56
71
  }
72
+ const verifyStart = performance.now();
57
73
  const result = await verifyAssertion(appInfo, extracted.assertion, clientData, deviceKey.publicKeyPem, deviceKey.signCount);
74
+ timings.verifyMs = performance.now() - verifyStart;
75
+ const commitStart = performance.now();
76
+ let committed;
58
77
  try {
59
- await options.updateSignCount(deviceId, result.signCount);
78
+ committed = await options.commitSignCount(deviceId, result.signCount);
60
79
  }
61
80
  catch (err) {
62
- throw new AssertionError(AssertionErrorCode.INTERNAL_ERROR, "Failed to update sign count", { cause: err });
81
+ throw new AssertionError(AssertionErrorCode.INTERNAL_ERROR, "Failed to commit sign count", { cause: err });
82
+ }
83
+ timings.commitMs = performance.now() - commitStart;
84
+ if (!committed) {
85
+ throw new AssertionError(AssertionErrorCode.SIGN_COUNT_STALE, `Sign count ${result.signCount} is stale — another concurrent request already advanced past it`);
63
86
  }
64
87
  newSignCount = result.signCount;
65
88
  }
@@ -76,6 +99,7 @@ export function withAssertion(options, handler) {
76
99
  deviceId,
77
100
  signCount: newSignCount,
78
101
  rawBody: clientData,
102
+ timings,
79
103
  });
80
104
  };
81
105
  }
@@ -0,0 +1,79 @@
1
+ import { AttestationError } from "./errors.js";
2
+ /**
3
+ * Library-internal timing spans for an attestation verification, in
4
+ * milliseconds. Exposed on {@linkcode AttestationContext.timings}.
5
+ */
6
+ export type AttestationTimings = {
7
+ /** Parse request body + decode base64 fields. */
8
+ extractMs: number;
9
+ /** `consumeChallenge` callback wall-clock duration. */
10
+ consumeChallengeMs: number;
11
+ /** Cryptographic verification (CBOR decode, cert chain, nonce, key extract). */
12
+ verifyMs: number;
13
+ /** `storeDeviceKey` callback wall-clock duration. */
14
+ storeDeviceKeyMs: number;
15
+ };
16
+ /** Context passed to the inner handler after successful attestation verification. */
17
+ export type AttestationContext = {
18
+ /** Device identifier (Apple-issued `keyId`) from the request. */
19
+ deviceId: string;
20
+ /** PEM-encoded ECDSA P-256 public key extracted from the attestation. */
21
+ publicKeyPem: string;
22
+ /** Initial sign count from the attestation (always `0`). */
23
+ signCount: number;
24
+ /** Raw App Attest receipt bytes. */
25
+ receipt: Uint8Array;
26
+ /** Library-internal timings, ready to merge into Server-Timing. */
27
+ timings: AttestationTimings;
28
+ };
29
+ /** Custom function to extract attestation data from an incoming request. */
30
+ export type ExtractAttestationFn = (req: Request) => Promise<{
31
+ deviceId: string;
32
+ challenge: Uint8Array;
33
+ attestation: Uint8Array;
34
+ }>;
35
+ /** Configuration for the {@linkcode withAttestation} middleware. */
36
+ export type WithAttestationOptions = {
37
+ /** Apple App ID in the format `TEAMID.bundleId`. */
38
+ appId: string;
39
+ /** Set to `true` for development environment attestations. */
40
+ developmentEnv?: boolean;
41
+ /**
42
+ * Atomically consume a previously-issued challenge. Return `true` if the
43
+ * challenge was valid, unused, and unexpired (and is now consumed);
44
+ * `false` otherwise. Implementations should use `DELETE ... RETURNING`
45
+ * to guarantee single-use semantics.
46
+ *
47
+ * The library converts `false` into `AttestationError(CHALLENGE_INVALID)`.
48
+ */
49
+ consumeChallenge: (challenge: Uint8Array) => Promise<boolean>;
50
+ /**
51
+ * Persist the verified device key row. Caller chooses INSERT vs UPSERT —
52
+ * re-attesting an existing deviceId is cryptographically safe (Apple has
53
+ * re-signed) so UPSERT is usually correct.
54
+ */
55
+ storeDeviceKey: (row: {
56
+ deviceId: string;
57
+ publicKeyPem: string;
58
+ signCount: number;
59
+ receipt: Uint8Array;
60
+ }) => Promise<void>;
61
+ /** Override the default body-based attestation extraction. */
62
+ extractAttestation?: ExtractAttestationFn;
63
+ /** Custom error response handler. Defaults to JSON error responses. */
64
+ onError?: (error: AttestationError, req: Request) => Response | Promise<Response>;
65
+ };
66
+ /**
67
+ * Request handler middleware that verifies App Attest attestations.
68
+ *
69
+ * Wraps a handler with automatic challenge consumption, cryptographic
70
+ * attestation verification, and device key persistence. Returns a new
71
+ * handler that rejects invalid attestations with appropriate HTTP
72
+ * error responses.
73
+ *
74
+ * The symmetric pair of {@linkcode withAssertion} — use this on your
75
+ * one-time device registration endpoint, then use `withAssertion` on
76
+ * every protected business endpoint.
77
+ */
78
+ export declare function withAttestation(options: WithAttestationOptions, handler: (req: Request, context: AttestationContext) => Response | Promise<Response>): (req: Request) => Promise<Response>;
79
+ //# sourceMappingURL=with-attestation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-attestation.d.ts","sourceRoot":"","sources":["../../src/src/with-attestation.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAwB,MAAM,aAAa,CAAC;AAErE;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,qFAAqF;AACrF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,OAAO,EAAE,UAAU,CAAC;IACpB,mEAAmE;IACnE,OAAO,EAAE,kBAAkB,CAAC;CAC7B,CAAC;AAEF,4EAA4E;AAC5E,MAAM,MAAM,oBAAoB,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,UAAU,CAAC;IACtB,WAAW,EAAE,UAAU,CAAC;CACzB,CAAC,CAAC;AAEH,oEAAoE;AACpE,MAAM,MAAM,sBAAsB,GAAG;IACnC,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;;;OAOG;IACH,gBAAgB,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D;;;;OAIG;IACH,cAAc,EAAE,CAAC,GAAG,EAAE;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,UAAU,CAAC;KACrB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpB,8DAA8D;IAC9D,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;IAC1C,uEAAuE;IACvE,OAAO,CAAC,EAAE,CACR,KAAK,EAAE,gBAAgB,EACvB,GAAG,EAAE,OAAO,KACT,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CACnC,CAAC;AAwEF;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,CACP,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,kBAAkB,KACxB,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,GAChC,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAkGrC"}
@@ -0,0 +1,135 @@
1
+ // src/with-attestation.ts
2
+ import { decodeBase64 } from "../deps/jsr.io/@std/encoding/1.0.10/base64.js";
3
+ import { verifyAttestation } from "./attestation.js";
4
+ import { AttestationError, AttestationErrorCode } from "./errors.js";
5
+ /**
6
+ * Default extractor: reads a JSON body of the shape
7
+ * `{ keyId: string, challenge: string, attestation: string }` where all
8
+ * three fields are base64-encoded per Apple's standard wire format.
9
+ */
10
+ async function defaultExtractAttestation(req) {
11
+ let body;
12
+ try {
13
+ body = await req.json();
14
+ }
15
+ catch (err) {
16
+ throw new AttestationError(AttestationErrorCode.INVALID_FORMAT, `Failed to parse attestation request body as JSON: ${err instanceof Error ? err.message : String(err)}`);
17
+ }
18
+ if (typeof body !== "object" || body === null ||
19
+ typeof body.keyId !== "string" ||
20
+ typeof body.challenge !== "string" ||
21
+ typeof body.attestation !== "string") {
22
+ throw new AttestationError(AttestationErrorCode.INVALID_FORMAT, "Attestation request body must include { keyId, challenge, attestation } as base64 strings");
23
+ }
24
+ const typed = body;
25
+ let challenge;
26
+ let attestation;
27
+ try {
28
+ challenge = decodeBase64(typed.challenge);
29
+ }
30
+ catch {
31
+ throw new AttestationError(AttestationErrorCode.INVALID_FORMAT, "challenge is not valid base64");
32
+ }
33
+ try {
34
+ attestation = decodeBase64(typed.attestation);
35
+ }
36
+ catch {
37
+ throw new AttestationError(AttestationErrorCode.INVALID_FORMAT, "attestation is not valid base64");
38
+ }
39
+ return { deviceId: typed.keyId, challenge, attestation };
40
+ }
41
+ function defaultErrorResponse(error) {
42
+ const status = error.code === AttestationErrorCode.INTERNAL_ERROR
43
+ ? 500
44
+ : error.code === AttestationErrorCode.INVALID_FORMAT
45
+ ? 400
46
+ : 401;
47
+ return new Response(JSON.stringify({ error: error.message, code: error.code }), { status, headers: { "Content-Type": "application/json" } });
48
+ }
49
+ /**
50
+ * Request handler middleware that verifies App Attest attestations.
51
+ *
52
+ * Wraps a handler with automatic challenge consumption, cryptographic
53
+ * attestation verification, and device key persistence. Returns a new
54
+ * handler that rejects invalid attestations with appropriate HTTP
55
+ * error responses.
56
+ *
57
+ * The symmetric pair of {@linkcode withAssertion} — use this on your
58
+ * one-time device registration endpoint, then use `withAssertion` on
59
+ * every protected business endpoint.
60
+ */
61
+ export function withAttestation(options, handler) {
62
+ const appInfo = {
63
+ appId: options.appId,
64
+ developmentEnv: options.developmentEnv ?? false,
65
+ };
66
+ const extract = options.extractAttestation ?? defaultExtractAttestation;
67
+ return async (req) => {
68
+ let deviceId;
69
+ let publicKeyPem;
70
+ let receipt;
71
+ const timings = {
72
+ extractMs: 0,
73
+ consumeChallengeMs: 0,
74
+ verifyMs: 0,
75
+ storeDeviceKeyMs: 0,
76
+ };
77
+ try {
78
+ const extractStart = performance.now();
79
+ const extracted = await extract(req);
80
+ timings.extractMs = performance.now() - extractStart;
81
+ deviceId = extracted.deviceId;
82
+ const consumeStart = performance.now();
83
+ let challengeOk;
84
+ try {
85
+ challengeOk = await options.consumeChallenge(extracted.challenge);
86
+ }
87
+ catch (err) {
88
+ // Static message — the original error is attached via `cause` and
89
+ // never reaches the wire. Callback errors from Postgres drivers
90
+ // routinely contain schema details, constraint names, and other
91
+ // info that must not leak to unauthenticated clients.
92
+ throw new AttestationError(AttestationErrorCode.INTERNAL_ERROR, "consumeChallenge callback failed", { cause: err });
93
+ }
94
+ timings.consumeChallengeMs = performance.now() - consumeStart;
95
+ if (!challengeOk) {
96
+ throw new AttestationError(AttestationErrorCode.CHALLENGE_INVALID, "Challenge is missing, expired, or already consumed");
97
+ }
98
+ const verifyStart = performance.now();
99
+ const result = await verifyAttestation(appInfo, deviceId, extracted.challenge, extracted.attestation);
100
+ timings.verifyMs = performance.now() - verifyStart;
101
+ publicKeyPem = result.publicKeyPem;
102
+ receipt = result.receipt;
103
+ const storeStart = performance.now();
104
+ try {
105
+ await options.storeDeviceKey({
106
+ deviceId,
107
+ publicKeyPem,
108
+ signCount: result.signCount,
109
+ receipt,
110
+ });
111
+ }
112
+ catch (err) {
113
+ // Static message — see consumeChallenge catch above.
114
+ throw new AttestationError(AttestationErrorCode.INTERNAL_ERROR, "storeDeviceKey callback failed", { cause: err });
115
+ }
116
+ timings.storeDeviceKeyMs = performance.now() - storeStart;
117
+ }
118
+ catch (err) {
119
+ // Non-AttestationError escapes (unexpected runtime errors, programmer
120
+ // bugs, etc.) are wrapped as INTERNAL_ERROR with a static message.
121
+ // The original is attached via `cause` and never reaches the wire.
122
+ const error = err instanceof AttestationError
123
+ ? err
124
+ : new AttestationError(AttestationErrorCode.INTERNAL_ERROR, "Internal error", { cause: err });
125
+ return options.onError?.(error, req) ?? defaultErrorResponse(error);
126
+ }
127
+ return await handler(req, {
128
+ deviceId,
129
+ publicKeyPem,
130
+ signCount: 0,
131
+ receipt,
132
+ timings,
133
+ });
134
+ };
135
+ }
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@bradford-tech/supabase-integrity-attest",
3
- "version": "0.3.2",
3
+ "version": "0.4.1",
4
4
  "description": "Verify Apple App Attest attestations and assertions using WebCrypto.",
5
+ "homepage": "https://integrity-attest.bradford.tech",
5
6
  "repository": {
6
7
  "type": "git",
7
8
  "url": "git+https://github.com/bradford-tech/supabase-integrity-attest.git"
@@ -22,18 +23,14 @@
22
23
  "import": "./esm/attestation.js"
23
24
  }
24
25
  },
25
- "scripts": {
26
- "test": "node test_runner.js"
27
- },
26
+ "scripts": {},
28
27
  "dependencies": {
29
28
  "@noble/curves": "^2.0.1",
30
29
  "asn1js": "^3.0.7",
31
30
  "cborg": "^4.5.8"
32
31
  },
33
32
  "devDependencies": {
34
- "@types/node": "^20.9.0",
35
- "picocolors": "^1.0.0",
36
- "@deno/shim-deno-test": "~0.5.0"
33
+ "@types/node": "^20.9.0"
37
34
  },
38
35
  "_generatedBy": "dnt@dev"
39
36
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"_dnt.test_polyfills.d.ts","sourceRoot":"","sources":["../src/_dnt.test_polyfills.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,KAAK;QACb,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;CACF;AAED,OAAO,EAAE,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"_dnt.test_shims.d.ts","sourceRoot":"","sources":["../src/_dnt.test_shims.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAK5C,eAAO,MAAM,aAAa;;CAA2C,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"almost_equals.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/almost_equals.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,MAAM,QAmBb"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"array_includes.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/array_includes.ts"],"names":[],"mappings":"AAMA,0FAA0F;AAC1F,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;AAOpD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,EACzB,GAAG,CAAC,EAAE,MAAM,GACX,IAAI,CAgCN"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"assert.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/assert.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,SAAK,GAAG,OAAO,CAAC,IAAI,CAI5D"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"assertion_error.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/assertion_error.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC;;;;OAIG;gBACS,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"equal.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/equal.ts"],"names":[],"mappings":"AA0FA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAgHrD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"equals.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/equals.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,CAAC,EACX,GAAG,CAAC,EAAE,MAAM,QAmBb"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"exists.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/exists.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,CAAC,EACT,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC,CAAC,CAOlC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"fail.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/fail.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AACH,wBAAgB,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,CAGxC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"false.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/false.ts"],"names":[],"mappings":"AAIA,uDAAuD;AACvD,MAAM,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC;AAE3D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,SAAK,GAAG,OAAO,CAAC,IAAI,IAAI,KAAK,CAI1E"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"greater.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/greater.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,QAMpE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"greater_or_equal.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/greater_or_equal.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,CAAC,EACX,GAAG,CAAC,EAAE,MAAM,QASb"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"instance_of.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/instance_of.ts"],"names":[],"mappings":"AAIA,sBAAsB;AAEtB,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;AACzD,4BAA4B;AAC5B,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,cAAc,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;AAE3E;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAE9B,CAAC,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAE9C,MAAM,EAAE,OAAO,EACf,YAAY,EAAE,CAAC,EACf,GAAG,SAAK,GACP,OAAO,CAAC,MAAM,IAAI,YAAY,CAAC,CAAC,CAAC,CA6BnC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"is_error.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/is_error.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,EACnD,KAAK,EAAE,OAAO,EAEd,UAAU,CAAC,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAC/C,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAC5B,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,KAAK,IAAI,CAAC,CA8BpB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"less.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/less.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,QAMjE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"less_or_equal.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/less_or_equal.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,CAAC,EACX,GAAG,CAAC,EAAE,MAAM,QASb"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/match.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,QAMb"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/mod.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;GAeG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"not_equals.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/not_equals.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,QAUtE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"not_instance_of.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/not_instance_of.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,CAAC,EACtC,MAAM,EAAE,CAAC,EAET,cAAc,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAClD,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAKjC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"not_match.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/not_match.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,QAMb"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"not_strict_equals.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/not_strict_equals.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,CAAC,EACX,GAAG,CAAC,EAAE,MAAM,QAYb"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"object_match.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/object_match.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,iBAAiB,CAE/B,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,EAChC,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,EACtC,GAAG,CAAC,EAAE,MAAM,GACX,IAAI,CAUN"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"rejects.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/rejects.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,MAAM,WAAW,CAAC,OAAO,CAAC,EAC9B,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAAC;AACpB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,EACnD,EAAE,EAAE,MAAM,WAAW,CAAC,OAAO,CAAC,EAE9B,UAAU,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAC9C,WAAW,CAAC,EAAE,MAAM,EACpB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,CAAC,CAAC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"strict_equals.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/strict_equals.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,CAAC,EACX,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,IAAI,CAAC,CAgCrB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"string_includes.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/string_includes.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,QAMb"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"throws.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/throws.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAC1B,EAAE,EAAE,MAAM,OAAO,EACjB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC;AACX;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,EAClD,EAAE,EAAE,MAAM,OAAO,EAEjB,UAAU,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAC9C,WAAW,CAAC,EAAE,MAAM,EACpB,GAAG,CAAC,EAAE,MAAM,GACX,CAAC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"unimplemented.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/unimplemented.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,CAGjD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"unreachable.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.19/unreachable.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,CAG/C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"build_message.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/internal/1.0.12/build_message.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,QAAQ;AAClB;;;GAGG;AACH,UAAU,UAAQ,GACjB,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAWvB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CASrD;AAED,4CAA4C;AAC5C,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,aAAa,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAC7C,OAAO,GAAE,mBAAwB,EACjC,YAAY,CAAC,EAAE,CACb,UAAU,EAAE,aAAa,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAC7C,UAAU,EAAE,OAAO,EACnB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,KAC1B,aAAa,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,GACrC,MAAM,EAAE,CA8BV"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/internal/1.0.12/diff.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEvD,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,CAAC,EAAE,MAAM,CAAC;IACV,2BAA2B;IAC3B,EAAE,EAAE,MAAM,CAAC;CACZ;AAMD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAanD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,aAAa,CAWvE;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,SAAS,CAAC,CAAC,EACzB,CAAC,EAAE,CAAC,EAAE,EACN,CAAC,EAAE,CAAC,EAAE,EACN,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,WAAW,EACnB,kBAAkB,EAAE,MAAM,GACzB,KAAK,CAAC;IACP,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,CAAC,CAAC;CACV,CAAC,CAgCD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,QAAQ,CACtB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,EAAE,WAAW,EACnB,kBAAkB,EAAE,MAAM,EAC1B,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,aAAa,EACrB,IAAI,CAAC,EAAE,aAAa,GACnB,aAAa,CAsBf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,CAwEvD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"diff_str.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/internal/1.0.12/diff_str.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAqB,UAAU,EAAE,MAAM,YAAY,CAAC;AAGhE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAY/C;AAKD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,UAAQ,GAAG,MAAM,EAAE,CAiBnE;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,EACxB,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,GAC3B,UAAU,CAAC,MAAM,CAAC,EAAE,CAetB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,EAAE,CAkDlE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/internal/1.0.12/format.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,SAAS,GAAG,CACtB,CAAC,EAAE,OAAO,EACV,OAAO,EAAE;IACP,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,KACE,MAAM,CAAC;AAEZ;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAmBzC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/internal/1.0.12/styles.ts"],"names":[],"mappings":"AAqCA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAExC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAExC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAWD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/internal/1.0.12/types.ts"],"names":[],"mappings":"AAGA,kDAAkD;AAClD,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;AAEvE;;;GAGG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAChC,IAAI,EAAE,QAAQ,GAAG,YAAY,CAAC;IAC9B,KAAK,EAAE,CAAC,CAAC;CACV,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IACjC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IAC1B,KAAK,EAAE,CAAC,CAAC;IACT,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;CAC3B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"cose.d.ts","sourceRoot":"","sources":["../../src/src/cose.ts"],"names":[],"mappings":"AAGA,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,UAAU,GAAG,UAAU,CAkBvE;AAED,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC,SAAS,CAAC,CASpB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"assertion-entry.test.d.ts","sourceRoot":"","sources":["../../src/tests/assertion-entry.test.ts"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"assertion.test.d.ts","sourceRoot":"","sources":["../../src/tests/assertion.test.ts"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"attestation-entry.test.d.ts","sourceRoot":"","sources":["../../src/tests/attestation-entry.test.ts"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"attestation.test.d.ts","sourceRoot":"","sources":["../../src/tests/attestation.test.ts"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"authdata.test.d.ts","sourceRoot":"","sources":["../../src/tests/authdata.test.ts"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"certificate.test.d.ts","sourceRoot":"","sources":["../../src/tests/certificate.test.ts"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"cose.test.d.ts","sourceRoot":"","sources":["../../src/tests/cose.test.ts"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"der.test.d.ts","sourceRoot":"","sources":["../../src/tests/der.test.ts"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.test.d.ts","sourceRoot":"","sources":["../../src/tests/errors.test.ts"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"apple-attestation.d.ts","sourceRoot":"","sources":["../../../src/tests/fixtures/apple-attestation.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,eAAO,MAAM,iBAAiB;;;;IAK5B,oDAAoD;;IAIpD,oDAAoD;;;;;;;;CAQrD,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-assertion.d.ts","sourceRoot":"","sources":["../../../src/tests/fixtures/generate-assertion.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,UAAU,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,aAAa,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,wBAAwB,CAAC,CAuDnC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.test.d.ts","sourceRoot":"","sources":["../../src/tests/utils.test.ts"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"with-assertion.test.d.ts","sourceRoot":"","sources":["../../src/tests/with-assertion.test.ts"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}