/** * Verify Apple App Attest attestations and assertions using WebCrypto. * * This library implements Apple's full * [App Attest](https://developer.apple.com/documentation/devicecheck/establishing-your-app-s-integrity) * server-side verification — CBOR decoding, X.509 certificate chain * validation, nonce verification, ECDSA signature checks — using only * WebCrypto APIs so it runs in Supabase Edge Functions, Deno Deploy, * and other edge runtimes with no native dependencies. * * ## Attestation * * Verify a new device and extract its public key: * * ```ts * import { verifyAttestation } from "@bradford-tech/supabase-integrity-attest"; * * // clientDataHash = SHA-256(challenge) — most client SDKs hash internally * const clientDataHash = new Uint8Array( * await crypto.subtle.digest("SHA-256", new TextEncoder().encode(challenge)), * ); * const { publicKeyPem, receipt, signCount } = await verifyAttestation( * { appId: "TEAMID.com.example.app" }, * keyId, * clientDataHash, * attestation, * ); * // Store publicKeyPem and signCount for future assertion verification * ``` * * ## Assertion * * Verify ongoing requests from an already-attested device: * * ```ts * import { verifyAssertion } from "@bradford-tech/supabase-integrity-attest"; * * const { signCount } = await verifyAssertion( * { appId: "TEAMID.com.example.app" }, * assertion, * clientData, * publicKeyPem, * previousSignCount, * ); * // Persist the updated signCount * ``` * * ## Middleware * * Use the {@linkcode withAttestation} and {@linkcode withAssertion} * wrappers for automatic verification, callback-driven storage, and * typed error handling: * * ```ts * import { * withAttestation, * withAssertion, * } from "@bradford-tech/supabase-integrity-attest"; * * const attestHandler = withAttestation( * { * appId: "TEAMID.com.example.app", * consumeChallenge, * storeDeviceKey, * }, * (_req, ctx) => * Response.json({ ok: true, deviceId: ctx.deviceId }), * ); * * const protectedHandler = withAssertion( * { * appId: "TEAMID.com.example.app", * getDeviceKey, * commitSignCount, * }, * (_req, ctx) => * Response.json({ hello: ctx.deviceId, counter: ctx.signCount }), * ); * ``` * * ## Subpath imports * * For smaller bundles, import only what you need: * * - `@bradford-tech/supabase-integrity-attest/attestation` — attestation * (`verifyAttestation`, `withAttestation`). Full crypto deps. * - `@bradford-tech/supabase-integrity-attest/assertion` — assertion * (`verifyAssertion`, `withAssertion`). Excludes `asn1js` and * `@noble/curves` to keep the bundle minimal. * * Full documentation: {@link https://integrity-attest.bradford.tech} * * @module */ export type { AppInfo, AttestationResult, VerifyAttestationOptions, } from "./src/attestation.js"; export type { AssertionAppInfo, AssertionResult } from "./src/assertion.js"; export { verifyAttestation } from "./src/attestation.js"; export { verifyAssertion } from "./src/assertion.js"; export { AssertionError, AssertionErrorCode, AttestationError, AttestationErrorCode, } from "./src/errors.js"; export { withAssertion } from "./src/with-assertion.js"; export { DEFAULT_ASSERTION_HEADER, DEFAULT_DEVICE_ID_HEADER, } from "./src/with-assertion.js"; export type { AssertionContext, AssertionTimings, DeviceKey, ExtractAssertionFn, WithAssertionOptions, } from "./src/with-assertion.js"; export { withAttestation } from "./src/with-attestation.js"; export type { AttestationContext, AttestationTimings, ExtractAttestationFn, WithAttestationOptions, } from "./src/with-attestation.js";