[
  {
    "path": ".electron_flags.sh",
    "content": "echo $(electron -i <<< 'process.exit(0)' 2> /dev/null | grep \"Using\" | awk '{$1=$1};1' | sed -r \"s/\\x1B\\[([0-9]{1,3}(;[0-9]{1,2};?)?)?[mGK]//g\")\n\nelectron -i <<< 'process.exit(parseInt(process.versions.node, 10))' &> /dev/null\nNODE_VERSION=$?\nexport NODE_OPTIONS='--enable-source-maps --import=tsx/esm'\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.yml",
    "content": "name: 🐞Bug report\ndescription: There's a bug I want to report\nlabels:\n  - triage\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill out this bug report. Do not use this form to ask questions or make suggestions, use the [appropriate](https://github.com/panva/jose/issues/new/choose) Discussions Topic for those.\n  - type: textarea\n    attributes:\n      label: What happened?\n      description: A clear and concise description of what the bug is and what you expected to happen instead.\n    validations:\n      required: true\n  - type: input\n    attributes:\n      label: Version\n      description: What exact version of the library do you use?\n      placeholder: e.g. v3.14.0\n    validations:\n      required: true\n  - type: dropdown\n    attributes:\n      label: Runtime\n      description: What runtime are you seeing the problem on?\n      options:\n        - Select an option\n        - Browser\n        - Bun\n        - Cloudflare Workers\n        - Deno\n        - Electron\n        - Node.js\n        - Other (I will specify below)\n    validations:\n      required: true\n  - type: input\n    attributes:\n      label: Runtime Details\n      description: More information about the runtime (e.g. node version, browser vendor and version, electron version, operating system)\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Code to reproduce\n      description: Please copy and paste code to reproduce the issue.\n      render: js\n    validations:\n      required: true\n  - type: checkboxes\n    attributes:\n      label: Required\n      options:\n        - label: I have searched the issues tracker and discussions for similar topics and couldn't find anything related.\n          required: true\n        - label: I agree to follow this project's [Code of Conduct](https://github.com/panva/jose/blob/main/CODE_OF_CONDUCT.md)\n          required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: ❓ Question\n    url: https://github.com/panva/jose/discussions/new?category=q-a\n    about:\n      Have a question about using jose? Head over to the discussions \"Q&A\" Category\n  - name: 💡 Feature proposal\n    url: https://github.com/panva/jose/discussions/new?category=ideas\n    about:\n      Have a proposal for a new feature? Head over to the discussions \"Ideas\" Category\n  - name: Support the project\n    url: https://github.com/sponsors/panva\n    about:\n      Are you asking your nth question? Relying on jose for critical operations? Consider\n      supporting the project so that it may continue being maintained.\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n    groups:\n      actions:\n        patterns:\n          - \"*\"\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "name: Build\n\npermissions: {}\n\non:\n  workflow_call:\n    outputs:\n      cache-key:\n        value: ${{ jobs.build.outputs.cache-key }}\n\njobs:\n  build:\n    concurrency: build-${{ github.ref }}\n    runs-on: ubuntu-latest\n    outputs:\n      cache-key: ${{ steps.cache-key.outputs.value }}\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n      - name: Setup node\n        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n        with:\n          node-version: lts/*\n          cache: 'npm'\n      - run: npm clean-install\n      - id: cache-key\n        run: echo \"value=dist-${{ hashFiles('src/**/*.ts', 'tsconfig/*.json', '.github/workflows/*.yml', 'package-lock.json') }}\" >> $GITHUB_OUTPUT\n      - name: Cache dist\n        uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4\n        id: dist\n        with:\n          path: dist\n          key: ${{ steps.cache-key.outputs.value }}\n      - name: Build\n        run: npm run build-all\n        if: ${{ steps.dist.outputs.cache-hit != 'true' }}\n      - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0\n        with:\n          name: dist\n          path: dist\n      - run: git reset HEAD --hard\n"
  },
  {
    "path": ".github/workflows/lock.yml",
    "content": "name: \"Lock threads\"\n\npermissions: {}\n\non:\n  schedule:\n    - cron: '11 11 * * 1'\n\njobs:\n  lock:\n    permissions:\n      issues: write\n      pull-requests: write\n      discussions: write\n    continue-on-error: true\n    runs-on: ubuntu-latest\n    steps:\n      - uses: dessant/lock-threads@7266a7ce5c1df01b1c6db85bf8cd86c737dadbe7 # v6.0.0\n        with:\n          github-token: ${{ github.token }}\n          issue-inactive-days: \"90\"\n          issue-lock-reason: \"\"\n          pr-inactive-days: \"90\"\n          pr-lock-reason: \"\"\n          discussion-inactive-days: \"90\"\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\n\npermissions: {}\n\non:\n  push:\n    tags: ['v6.[0-9]+.[0-9]+']\n\njobs:\n  build:\n    uses: ./.github/workflows/build.yml\n\n  npm:\n    needs:\n      - build\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      id-token: write\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n        with:\n          fetch-depth: 0\n      - name: Setup node\n        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n        with:\n          node-version: lts/*\n          registry-url: https://registry.npmjs.org\n      - name: Load cached dist\n        uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4\n        id: dist\n        with:\n          path: dist\n          key: dist-${{ hashFiles('src/**/*.ts', 'tsconfig/*.json', '.github/workflows/*.yml', 'package-lock.json') }}\n          fail-on-cache-miss: true\n      - name: Prepare distribution\n        run: node tools/publish.cjs\n      - run: npm publish\n\n  jsr:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      id-token: write\n    steps:\n      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n        with:\n          fetch-depth: 0\n      - run: npx jsr publish\n\n  cleanup:\n    needs:\n      - npm\n      - jsr\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n        with:\n          fetch-depth: 0\n      - run: git push origin $GITHUB_SHA:v6.x\n      - run: git rm -r dist\n      - run: |\n          git config --local user.name \"github-actions[bot]\"\n          git config --local user.email \"41898282+github-actions[bot]@users.noreply.github.com\"\n          git commit -m \"chore: cleanup after release\"\n      - run: git push origin HEAD:main\n\n  github:\n    needs:\n      - npm\n      - jsr\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n      discussions: write\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n        with:\n          fetch-depth: 2\n      - name: Setup node\n        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n        with:\n          node-version: lts/*\n          cache: 'npm'\n      - run: node tools/release-notes.cjs\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/retry.yml",
    "content": "name: Retry\n\npermissions: {}\n\non:\n  workflow_run:\n    workflows:\n      - Test\n    types:\n      - completed\n\njobs:\n  retry:\n    permissions:\n      actions: write\n    runs-on: ubuntu-latest\n    if: ${{ github.repository == 'panva/jose' && github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.run_attempt == 1 }}\n    steps:\n      - run: gh api -XPOST ${{ github.event.workflow_run.rerun_url }}-failed-jobs\n        env:\n          GH_TOKEN: ${{ github.token }}\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: Test\n\npermissions: {}\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n  schedule:\n    - cron: '11 11 * * 1'\n  workflow_dispatch:\n\njobs:\n  build:\n    uses: ./.github/workflows/build.yml\n\n  node-versions:\n    uses: panva/.github/.github/workflows/node-versions.yml@main\n    with:\n      min: 20\n\n  node:\n    needs:\n      - node-versions\n    strategy:\n      fail-fast: false\n      matrix:\n        node-version: ${{ fromJSON(needs.node-versions.outputs.matrix) }}\n        suite:\n          - tap:node\n          - test\n\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n      - name: Setup node\n        id: node\n        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n        with:\n          node-version: ${{ matrix.node-version }}\n          cache: 'npm'\n          check-latest: true\n      - run: npm clean-install\n      - name: Run Test Suite\n        run: npm run ${{ matrix.suite }}\n\n  deno:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n      - uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2.0.4\n        with:\n          deno-version: latest\n      - name: Setup node\n        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n        with:\n          node-version: lts/*\n          cache: 'npm'\n      - run: npm clean-install\n      - name: Test Deno Definitions\n        run: |\n          npm run build:deno\n          deno check dist/deno/index.ts\n      - name: Test Deno\n        run: npm run tap:deno\n\n  bun:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n      - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0\n        with:\n          bun-version: latest\n      - name: Setup node\n        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n        with:\n          node-version: lts/*\n          cache: 'npm'\n      - run: npm clean-install\n      - name: Test Bun\n        run: npm run tap:bun\n\n  workerd:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n      - name: Setup node\n        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n        with:\n          node-version: lts/*\n          cache: 'npm'\n      - run: npm clean-install\n      - run: npm install --global workerd\n      - run: npm link workerd\n      - name: Run Test Suite\n        run: npm run tap:workerd\n\n  browsers:\n    runs-on: macos-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        browser: [chromium, firefox, safari]\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n      - name: Setup node\n        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n        with:\n          node-version: lts/*\n          cache: 'npm'\n      - run: npm clean-install\n      - run: npm upgrade playwright\n      - name: get playwright version\n        id: playwright-version\n        run:\n          echo \"version=$(npm list playwright --json | jq -r '.dependencies[\"@playwright/test\"].dependencies.playwright.version')\" >>\n          $GITHUB_OUTPUT\n      - uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4\n        with:\n          path: ~/Library/Caches/ms-playwright\n          key: playwright-${{ runner.os }}-${{ steps.playwright-version.outputs.version }}\n      - run: npx playwright install --only-shell chromium firefox webkit\n      - name: Run Test Suite\n        run: npm run tap:browsers\n        env:\n          BROWSER: ${{ matrix.browser }}\n\n  electron:\n    runs-on: macos-15\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n      - name: Setup node\n        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n        with:\n          node-version: lts/*\n          cache: 'npm'\n      - run: npm clean-install\n      - name: Install Electron\n        run: npm install --global electron\n      - name: Run Test Suite\n        run: npm run tap:electron\n"
  },
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directory and lockfiles\nnode_modules/\njspm_packages/\nyarn.lock\nnpm-shrinkwrap.json\n\n# Snowpack dependency directory (https://snowpack.dev/)\nweb_modules/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Microbundle cache\n.rpt2_cache/\n.rts2_cache_cjs/\n.rts2_cache_es/\n.rts2_cache_umd/\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n.env.test\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n.parcel-cache\n\n# Next.js build output\n.next\nout\n\n# Nuxt.js build / generate output\n.nuxt\ndist\ndist-browser-tests\n\n# Gatsby files\n.cache/\n# Comment in the public line in if your project uses Gatsby and not Next.js\n# https://nextjs.org/blog/next-9-1#public-directory-support\n# public\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n# TernJS port file\n.tern-port\n\n# Stores VSCode versions used for testing VSCode extensions\n.vscode-test\n\n# yarn v2\n.yarn/cache\n.yarn/unplugged\n.yarn/build-state.yml\n.yarn/install-state.gz\n.pnp.*\n\n\n.npmrc\ntap/*.js\ntap/*.js.map\ntap/run-*.mjs\ntap/run-*.mjs.map\ntap/run-*.cjs\ntap/run-*.cjs.map\n*.bak\n*.bun\ntap/.workerd.capnp\ntap/.workers.capnp\ntest-results/.last-run.json\n"
  },
  {
    "path": ".node_flags.sh",
    "content": "echo \"Using Node.js $(node --version)\"\n\nnode -e 'process.exit(parseInt(process.versions.node, 10))' &> /dev/null\nNODE_VERSION=$?\nexport NODE_OPTIONS='--enable-source-maps --import=tsx/esm'\n"
  },
  {
    "path": ".prettierignore",
    "content": "# Ignore artifacts:\nbuild\ndist\ncoverage\n"
  },
  {
    "path": ".prettierrc.json",
    "content": "{\n  \"trailingComma\": \"all\",\n  \"singleQuote\": true,\n  \"printWidth\": 100,\n  \"semi\": false,\n  \"plugins\": [\"prettier-plugin-jsdoc\"],\n  \"tsdoc\": true,\n  \"jsdocSeparateReturnsFromParam\": true,\n  \"jsdocSeparateTagGroups\": true,\n  \"jsdocPrintWidth\": 100\n}\n"
  },
  {
    "path": ".versionrc.json",
    "content": "{\n  \"commit-all\": true,\n  \"scripts\": {\n    \"prerelease\": \"node ./tools/prebump.cjs && npm run-script build-all\",\n    \"postbump\": \"node ./tools/postbump.cjs\",\n    \"postchangelog\": \"sed -i '' -e 's/### \\\\[/## [/g' CHANGELOG.md\"\n  },\n  \"types\": [\n    {\n      \"type\": \"feat\",\n      \"section\": \"Features\"\n    },\n    {\n      \"type\": \"fix\",\n      \"section\": \"Fixes\"\n    },\n    {\n      \"type\": \"chore\",\n      \"hidden\": true\n    },\n    {\n      \"type\": \"docs\",\n      \"section\": \"Documentation\",\n      \"hidden\": false\n    },\n    {\n      \"type\": \"style\",\n      \"hidden\": true\n    },\n    {\n      \"type\": \"refactor\",\n      \"section\": \"Refactor\",\n      \"hidden\": false\n    },\n    {\n      \"type\": \"revert\",\n      \"section\": \"Reverts\",\n      \"hidden\": false\n    },\n    {\n      \"type\": \"perf\",\n      \"section\": \"Performance\",\n      \"hidden\": false\n    },\n    {\n      \"type\": \"test\",\n      \"hidden\": true\n    }\n  ]\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.\n\n## [6.2.2](https://github.com/panva/jose/compare/v6.2.1...v6.2.2) (2026-03-18)\n\n\n### Fixes\n\n* reject failed decompression with JWEInvalid error ([043b181](https://github.com/panva/jose/commit/043b181a96ee55d92b9ff1ee94e11be36e258ee4))\n\n## [6.2.1](https://github.com/panva/jose/compare/v6.2.0...v6.2.1) (2026-03-09)\n\n\n### Refactor\n\n* reorganize internals, less files, smaller footprint ([d4231f9](https://github.com/panva/jose/commit/d4231f9f2a654d203589a787bfa8a34fb03c87c5))\n\n## [6.2.0](https://github.com/panva/jose/compare/v6.1.3...v6.2.0) (2026-03-05)\n\n\n### Features\n\n* re-introduce JWE \"zip\" (Compression Algorithm) Header Parameter support ([b13b446](https://github.com/panva/jose/commit/b13b44688baeaf078259379c61f42569f5d63ab5))\n\n\n### Documentation\n\n* clarify return of general jws and jwe ([56682b4](https://github.com/panva/jose/commit/56682b4608eacafb7bcd6b63713d6434e0e6ad66))\n\n## [6.1.3](https://github.com/panva/jose/compare/v6.1.2...v6.1.3) (2025-12-02)\n\n\n### Refactor\n\n* avoid export * as for google closure's compiler sake ([6303d98](https://github.com/panva/jose/commit/6303d98efba00c9a3f8f3e814c85ac6e6944b11c)), closes [#832](https://github.com/panva/jose/issues/832)\n\n## [6.1.2](https://github.com/panva/jose/compare/v6.1.1...v6.1.2) (2025-11-15)\n\n\n### Refactor\n\n* fallback to checking instanceof for CryptoKey ([901cd90](https://github.com/panva/jose/commit/901cd908f325265c39f8af1f1505138e0a689f94)), closes [#765](https://github.com/panva/jose/issues/765) [#803](https://github.com/panva/jose/issues/803) [#821](https://github.com/panva/jose/issues/821) [#827](https://github.com/panva/jose/issues/827) [#828](https://github.com/panva/jose/issues/828)\n\n## [6.1.1](https://github.com/panva/jose/compare/v6.1.0...v6.1.1) (2025-11-09)\n\n\n### Documentation\n\n* add link to RFC9864 ([767edde](https://github.com/panva/jose/commit/767edde5bde07c60e2c1b1db365ad234a9ae5195))\n* link to ML-DSA for JOSE ([ed4252c](https://github.com/panva/jose/commit/ed4252ca8ed084e734a53b214f62e3da11c39857))\n* remove mention of Edge Runtime from the readme ([94fdde7](https://github.com/panva/jose/commit/94fdde702498f5e94ec3307f85f120f43a527590))\n* update README.md ([25098ef](https://github.com/panva/jose/commit/25098ef7518be732bbef3ea6ed87b0d61a85f581))\n\n\n### Refactor\n\n* eliminate named exports in the source code ([f6ae30d](https://github.com/panva/jose/commit/f6ae30d5d86c376269ffa853f62e403d13d4f610))\n* expose setKeyManagementParameters also on a GeneralEncrypt Recipient ([16e6b23](https://github.com/panva/jose/commit/16e6b230ee29662c599c556b91a2c367f0fa088c))\n* faster path for symmetric key checks ([a44c2ec](https://github.com/panva/jose/commit/a44c2ec6351fb639816846ec8b23f5f084a3d9fb))\n* improve en/decoding overheads ([daee426](https://github.com/panva/jose/commit/daee4265c9ab218acbcdb1d7b10c3c728447240b))\n\n## [6.1.0](https://github.com/panva/jose/compare/v6.0.13...v6.1.0) (2025-08-27)\n\n\n### Features\n\n* support AKP JWKs in calculateJwkThumbprint and calculateJwkThumbprintUri ([cf2092a](https://github.com/panva/jose/commit/cf2092a2b51c9fb67049e96ee22d551ad34c0b2c))\n* support for the ML-DSA PQC Algorithm Identifiers ([25ddce4](https://github.com/panva/jose/commit/25ddce491ba3968e8802db5913e49a52224246be))\n\n## [6.0.13](https://github.com/panva/jose/compare/v6.0.12...v6.0.13) (2025-08-21)\n\n\n### Refactor\n\n* more readability in ecdhes.ts ([84da9de](https://github.com/panva/jose/commit/84da9decd8b2f266a343a507b6b79197f2da11e8))\n* update asn1.ts helpers ([b4f8fb3](https://github.com/panva/jose/commit/b4f8fb372689b5b38074aa45c9921a6a997a9142))\n\n## [6.0.12](https://github.com/panva/jose/compare/v6.0.11...v6.0.12) (2025-07-15)\n\n\n### Documentation\n\n* add known caveats to customFetch ([02e1f1e](https://github.com/panva/jose/commit/02e1f1e87c764885121590aa2af80c831a9320ab))\n* mention the apu/apv parameter names in setKeyManagementParameters ([6274d5a](https://github.com/panva/jose/commit/6274d5abca3d3882d3d722415f064fee5c44d0e4))\n* update compact setKeyManagementParameters ([2f44381](https://github.com/panva/jose/commit/2f44381b6b0e30cf538ea2edb0d42b76a61de1f8))\n* use GitHub Flavored Markdown for notes and warnings ([f6b4ffc](https://github.com/panva/jose/commit/f6b4ffcd82d9645d9b818ece09a09b5a636b69c9))\n\n\n### Refactor\n\n* createPublicKey is not a constructor ([61ded78](https://github.com/panva/jose/commit/61ded787150c6ae13eeb65b6680f857d6657465f))\n* update asn1.ts helper functions ([b2b611c](https://github.com/panva/jose/commit/b2b611c426eeed3c40c3a1423d8a02dd46f3f7e8))\n\n## [6.0.11](https://github.com/panva/jose/compare/v6.0.10...v6.0.11) (2025-05-05)\n\n\n### Fixes\n\n* typ checking edge-cases when it contains a slash (/) character ([31e4baf](https://github.com/panva/jose/commit/31e4bafc0a908cac044bbe34c7024f4eac9c974f))\n\n## [6.0.10](https://github.com/panva/jose/compare/v6.0.9...v6.0.10) (2025-03-12)\n\n\n### Refactor\n\n* removed unused claims methods ([74719cf](https://github.com/panva/jose/commit/74719cfcfba1920b87740245da08bb70b68e7cd1))\n* reorganize jwt claim set utils ([1f12d88](https://github.com/panva/jose/commit/1f12d88ee8cfa328126934a7020396f9a8dd8932))\n\n## [6.0.9](https://github.com/panva/jose/compare/v6.0.8...v6.0.9) (2025-03-11)\n\n\n### Documentation\n\n* add more symbol document, ignore ts-private fields ([8b73687](https://github.com/panva/jose/commit/8b73687595a7ca608aa1b78870b6b165ad5249f2))\n* bump typedoc ([6163a8b](https://github.com/panva/jose/commit/6163a8b6a773100ed31d207b598db1259a7e13a8))\n* drop cdnjs links in README ([a910038](https://github.com/panva/jose/commit/a9100383ab16cb62c375401fac08a77f3c6c528d))\n* drop denoland/x links in README and add jsr ([3662b9e](https://github.com/panva/jose/commit/3662b9ec44403bd501fc895bea4ded623d23e7e1))\n* fix key export links from docs/README.md ([c8edfc2](https://github.com/panva/jose/commit/c8edfc29416d3339f6c78fdc42bdfdfadaa5cf7e))\n\n\n### Refactor\n\n* always assume structuredClone is present ([f7898a9](https://github.com/panva/jose/commit/f7898a9487508684dbbeba990e0cc96d344b1ff6))\n* hide internal private fields and drop ProduceJWT inheritance ([ab18881](https://github.com/panva/jose/commit/ab18881a57524897aec300c9bf7bbd73d9e3447c))\n* less objects when JWE JWT Replicated Header Parameters are used ([c763a0e](https://github.com/panva/jose/commit/c763a0e373b0e814dc4705dd2eb7daa614eae43a))\n\n## [6.0.8](https://github.com/panva/jose/compare/v6.0.7...v6.0.8) (2025-02-26)\n\n\n### Fixes\n\n* export [customFetch] symbol from the default entrypoint ([1615614](https://github.com/panva/jose/commit/1615614964b4a66ac888f470bad94b6dee7009bc)), closes [#762](https://github.com/panva/jose/issues/762)\n\n## [6.0.7](https://github.com/panva/jose/compare/v6.0.6...v6.0.7) (2025-02-25)\n\n\n### Documentation\n\n* improve generate key/secret and import function descriptions ([cd06359](https://github.com/panva/jose/commit/cd06359597a3b8e5c30892142f3d750eded2fbce))\n\n\n### Fixes\n\n* use [customFetch] when provided to createRemoteJWKSet ([35f6509](https://github.com/panva/jose/commit/35f6509ff45927d9f55f3b5c09f96f459e60136a)), closes [#760](https://github.com/panva/jose/issues/760)\n\n## [6.0.6](https://github.com/panva/jose/compare/v6.0.5...v6.0.6) (2025-02-23)\n\n\n### Refactor\n\n* move base64url around ([e1350ef](https://github.com/panva/jose/commit/e1350eff8786b92eead82258dc2d5b9db128b523))\n\n\n### Documentation\n\n* add various exported symbol descriptions ([3b8ff71](https://github.com/panva/jose/commit/3b8ff717ad2054c1c50f72bcc866f08cd672b49d))\n* add various exported symbol descriptions ([fc4e7da](https://github.com/panva/jose/commit/fc4e7dab4c7021d5d2f23a55de93c9ed35b79cef))\n* add various exported symbol descriptions ([74f02c8](https://github.com/panva/jose/commit/74f02c833e057ab419173be7b8b8140eddcfc19f))\n* update base64url function descriptions ([03d72c8](https://github.com/panva/jose/commit/03d72c8a5578bd442190724ca05994b0856432d5))\n\n## [6.0.5](https://github.com/panva/jose/compare/v6.0.4...v6.0.5) (2025-02-23)\n\n\n### Refactor\n\n* **types:** make JWKParameters.kty compatible with @types/node and @types/web ([bb6ccfe](https://github.com/panva/jose/commit/bb6ccfed3efd5c84c540c2a1f621b9d2951f2b84))\n\n\n### Documentation\n\n* add various exported symbol descriptions ([f52c2ff](https://github.com/panva/jose/commit/f52c2ff0c3edbe30b32a4c9858199bfbc9f9367e))\n\n## [6.0.4](https://github.com/panva/jose/compare/v6.0.3...v6.0.4) (2025-02-22)\n\n\n### Refactor\n\n* optimize base64 with tc39/proposal-arraybuffer-base64 ([8a0da69](https://github.com/panva/jose/commit/8a0da6968ec2813ced80962e847a89676ef9e8af)), closes [#752](https://github.com/panva/jose/issues/752)\n* update getSPKI to use crypto.createPublicKey when available ([92392a0](https://github.com/panva/jose/commit/92392a0aa278ecf419a8b0b6a984c72d071125ad)), closes [#752](https://github.com/panva/jose/issues/752)\n* use Double HMAC pattern for AES-CBC tag comparison ([f3ba4c7](https://github.com/panva/jose/commit/f3ba4c715f3ff5baef624bbb62771398de488166)), closes [#752](https://github.com/panva/jose/issues/752)\n\n## [6.0.3](https://github.com/panva/jose/compare/v6.0.2...v6.0.3) (2025-02-22)\n\n\n### Documentation\n\n* remove root module tag so that README.md shows up on jsr.io ([ee70698](https://github.com/panva/jose/commit/ee7069818b6a3bc6df7aa7ab8060a90299ef0c9a))\n\n## [6.0.2](https://github.com/panva/jose/compare/v6.0.1...v6.0.2) (2025-02-22)\n\n\n### Documentation\n\n* add module tags to all entrypoints ([a5687aa](https://github.com/panva/jose/commit/a5687aaed475ba113dd01d8fddf95f5911c17d0f))\n\n## [6.0.1](https://github.com/panva/jose/compare/v6.0.0...v6.0.1) (2025-02-22)\n\n\n### Fixes\n\n* **types:** update build to include extensions in type imports ([9b96672](https://github.com/panva/jose/commit/9b96672ef79aabf07699e0ccafa5b54380f6330c))\n\n## [6.0.0](https://github.com/panva/jose/compare/v5.10.0...v6.0.0) (2025-02-22)\n\n\n### ⚠ BREAKING CHANGES\n\n* The PEMImportOptions type interface is renamed to KeyImportOptions.\n* all builds and bundles now use ES2022 as target\n* createRemoteJWKSet now uses fetch, because of that its Node.js only options.agent property has been removed and new fetch-related options were added\n* drop support for Ed448 and X448\n* drop support for JWK key_ops and CryptoKey usages \"(un)wrapKey\" and \"deriveKey\"\n* resolved keys returned as part of verify/decrypt operations (when get key functions are used) are always normalized to either Uint8Array / CryptoKey depending on what's more efficient for the executed operation\n* Key \"Type\" Generics are removed\n* CJS-style require is now only possible when require(esm) support is present in the Node.js runtime\n* private KeyObject instances can no longer be used for verify operations\n* private KeyObject instances can no longer be used for encryption operations\n* generateSecret, generateKeyPair, importPKCS8, importSPKI, importJWK, and importX509 now yield a CryptoKey instead of a KeyObject in Node.js\n* drop support for Node.js 18.x and earlier\n* runtime-specific npm releases (jose-browser-runtime, jose-node-cjs-runtime, and jose-node-esm-runtime) are no longer maintained or supported\n* removed secp256k1 JWS support\n* removed deprecated experimental APIs\n* removed RSA1_5 JWE support\n\n### Features\n\n* enable CryptoKey and KeyObject inputs in JWK thumbprint functions ([6fc9c44](https://github.com/panva/jose/commit/6fc9c4461a1fa39b363185e866bd686044ee30c6))\n* JSON Web Key is now an allowed input everywhere ([ebda967](https://github.com/panva/jose/commit/ebda9674e9daf9b9d09568cf17b1a23d9cf20a60))\n\n\n### Refactor\n\n* always use infered CryptoKey ([c4abaa2](https://github.com/panva/jose/commit/c4abaa265ef56b517f868cf49db4ed8975446465))\n* backport the Ed25519 JWS Algorithm Identifier support ([7a94cb9](https://github.com/panva/jose/commit/7a94cb997af94ae2db61efbeb271e0555afc62d8))\n* drop support for Ed448 and X448 ([2fae1c4](https://github.com/panva/jose/commit/2fae1c447b621fb5dbdb1896c29c3a0772f26f44))\n* drop support for JWK key_ops and CryptoKey usages \"(un)wrapKey\" and \"deriveKey\" ([ef918be](https://github.com/panva/jose/commit/ef918be8bab1b8dc5ec30b026d85da8ce7e0b062))\n* ensure export functions continue to work with KeyObject inputs ([28e9e68](https://github.com/panva/jose/commit/28e9e684bbe15a1fa40631465b9688fdf1cecf0e))\n* hardcode the cryptoRuntime export since it is now always WebCryptoAPI ([e00f273](https://github.com/panva/jose/commit/e00f2737fdc7b44b3c9d8c581460617d64152ce2))\n* JWK import extractable default for public keys is now true ([64dcebe](https://github.com/panva/jose/commit/64dcebef368851863d11c3718f10bdbb1f0102c7))\n* PEM import extractable default for public keys is now true ([4e9f114](https://github.com/panva/jose/commit/4e9f1143c7c31176e55d2e75aea96ead16db4107))\n* removed deprecated APIs ([5352083](https://github.com/panva/jose/commit/5352083dc603f8f71acd34d969842be1881f3b19))\n* removed secp256k1 JWS support ([e2b58a5](https://github.com/panva/jose/commit/e2b58a5ca50a40559451179cdd15f62be831eda2))\n* restructure src/lib and src/runtime now that runtime is fixed ([9b236ce](https://github.com/panva/jose/commit/9b236cec4e66a588d0e7f27039a08a51db5abc49))\n* target is now ES2022 everywhere ([aa590d5](https://github.com/panva/jose/commit/aa590d569f7eff948f96e4e8210843668777c724))\n* update importJWK args to align with other import functions ([355a2dd](https://github.com/panva/jose/commit/355a2dd33a2466245f2872014110c9a1c0257c16))\n* WebCryptoAPI is now the only crypto used ([161de46](https://github.com/panva/jose/commit/161de466a29d90a1129e671ed3a23be556c77f27))\n\n## [5.10.0](https://github.com/panva/jose/compare/v5.9.6...v5.10.0) (2025-02-17)\n\n\n### Features\n\n* support fully specified Ed25519 algorithm identifier ([c39f57d](https://github.com/panva/jose/commit/c39f57d614ec7493ad7b1eeaf8ccdc51c499cd17))\n\n## [5.9.6](https://github.com/panva/jose/compare/v5.9.5...v5.9.6) (2024-10-20)\n\n\n### Reverts\n\n* Revert \"refactor(build): simplify package exports\" ([2ef3a52](https://github.com/panva/jose/commit/2ef3a5266e2f903aab2f8c9d43437151d7da0122))\n\n## [5.9.5](https://github.com/panva/jose/compare/v5.9.4...v5.9.5) (2024-10-20)\n\n\n### Refactor\n\n* **build:** simplify package exports ([4783f7f](https://github.com/panva/jose/commit/4783f7fcb0282c2e24479758614a82e3d7c0e627))\n\n## [5.9.4](https://github.com/panva/jose/compare/v5.9.3...v5.9.4) (2024-10-11)\n\n\n### Refactor\n\n* **types:** update error definitions ([510c5ca](https://github.com/panva/jose/commit/510c5ca4a7c5dce08b6dd358a7120ad18747c3c8))\n\n## [5.9.3](https://github.com/panva/jose/compare/v5.9.2...v5.9.3) (2024-09-22)\n\n\n### Refactor\n\n* use as Type for type assertions instead of <Type> ([c4dc24d](https://github.com/panva/jose/commit/c4dc24da1e6cec99dade1a82eecea423236d342e))\n\n## [5.9.2](https://github.com/panva/jose/compare/v5.9.1...v5.9.2) (2024-09-14)\n\n\n### Refactor\n\n* **types:** remove index signatures from JWK interfaces ([ccf0cda](https://github.com/panva/jose/commit/ccf0cdaa7166d9273a951356859172192ed1be3f))\n\n## [5.9.1](https://github.com/panva/jose/compare/v5.9.0...v5.9.1) (2024-09-13)\n\n\n### Fixes\n\n* **types:** add missing index signature on the convenience JWK types ([90a93dc](https://github.com/panva/jose/commit/90a93dc9ce5da294e91d2a964ed593299c464893))\n\n## [5.9.0](https://github.com/panva/jose/compare/v5.8.0...v5.9.0) (2024-09-13)\n\n\n### Features\n\n* allow JWK objects as \"key\" input to sign and verify ([c6302ea](https://github.com/panva/jose/commit/c6302ea6886974eb433c51ddcf6eff1bbfdf5459))\n\n## [5.8.0](https://github.com/panva/jose/compare/v5.7.0...v5.8.0) (2024-08-26)\n\n\n### Features\n\n* add subpath module exports ([72ecff6](https://github.com/panva/jose/commit/72ecff6574d252f407b6e145a166c995cdd85949))\n\n\n### Refactor\n\n* omit LocalJWKSet export since it's no longer needed for RemoteJWKSet ([c502731](https://github.com/panva/jose/commit/c502731fd888c165df32214f13333bc055d1d3f4))\n\n## [5.7.0](https://github.com/panva/jose/compare/v5.6.3...v5.7.0) (2024-08-19)\n\n\n### Features\n\n* graduate jwksCache to stable API ([0f09c12](https://github.com/panva/jose/commit/0f09c124529bf84f027e57ce1f769319e7d42185))\n\n## [5.6.3](https://github.com/panva/jose/compare/v5.6.2...v5.6.3) (2024-07-03)\n\n\n### Fixes\n\n* add sideEffects:false to nested ESM package.json files ([f3aff1c](https://github.com/panva/jose/commit/f3aff1cf018b62356e46a70e89aa96adeca6e686))\n\n## [5.6.2](https://github.com/panva/jose/compare/v5.6.1...v5.6.2) (2024-06-27)\n\n\n### Refactor\n\n* CryptoKey normalization is not always async ([b7751f5](https://github.com/panva/jose/commit/b7751f58743c837f5bc76df301430c9b7c72dd85))\n* weak cache normalized CryptoKey instances ([32b25a5](https://github.com/panva/jose/commit/32b25a5c94febe79dcfa7b2e62e432d1dce1cd44))\n\n\n### Fixes\n\n* ensure KeyObject type in Web API encrypt/decrypt ([b7920bd](https://github.com/panva/jose/commit/b7920bd635d1b7642307709e888ea3dcaf3e9b6f))\n\n## [5.6.1](https://github.com/panva/jose/compare/v5.6.0...v5.6.1) (2024-06-27)\n\n\n### Refactor\n\n* normalize is always defined for Web API runtimes ([7bcb103](https://github.com/panva/jose/commit/7bcb10392cb7ff6bd17ebeb27f95f334d799fdb8))\n\n\n### Fixes\n\n* workaround turbo's eager optimizations ([723a042](https://github.com/panva/jose/commit/723a04264e03daa5e311055ad2672e6ae5dfd1e3)), closes [#690](https://github.com/panva/jose/issues/690)\n\n## [5.6.0](https://github.com/panva/jose/compare/v5.5.0...v5.6.0) (2024-06-27)\n\n\n### Features\n\n* support KeyObject inputs in WebCryptoAPI runtimes given compatibility ([e178b8f](https://github.com/panva/jose/commit/e178b8f0fbdd0313f5327a8e9e48ef7233060e0c))\n\n## [5.5.0](https://github.com/panva/jose/compare/v5.4.1...v5.5.0) (2024-06-26)\n\n\n### Features\n\n* add experimental support for edge compute runtimes JWKS caching ([ab166e2](https://github.com/panva/jose/commit/ab166e207f1f2f63b1f1ab259e1280549b2e9097)), closes [#551](https://github.com/panva/jose/issues/551) [#661](https://github.com/panva/jose/issues/661) [#653](https://github.com/panva/jose/issues/653) [#415](https://github.com/panva/jose/issues/415)\n\n## [5.4.1](https://github.com/panva/jose/compare/v5.4.0...v5.4.1) (2024-06-18)\n\n\n### Fixes\n\n* ensure latest release on npm is v5.x ([a9b2a30](https://github.com/panva/jose/commit/a9b2a300947f9ab10d580748a3eda58207de4c62))\n\n## [5.4.0](https://github.com/panva/jose/compare/v5.3.0...v5.4.0) (2024-06-03)\n\n\n### Features\n\n* expose JWT's payload in JWTClaimValidationFailed instances ([58bcffb](https://github.com/panva/jose/commit/58bcffbac735cc727fd81c36813f12fd6f58b695)), closes [#680](https://github.com/panva/jose/issues/680)\n\n\n### Refactor\n\n* add explicit return types everywhere ([cc2b2d7](https://github.com/panva/jose/commit/cc2b2d7b76118d59b9e08c589dc33a45a6377f4a))\n\n## [5.3.0](https://github.com/panva/jose/compare/v5.2.4...v5.3.0) (2024-05-10)\n\n\n### Features\n\n* allow observing remote JWKS resolver state and its manual reload ([fa8b639](https://github.com/panva/jose/commit/fa8b639c277e1694b08a08c7152341b22ec1725d))\n\n\n### Refactor\n\n* if should not be the only statement in else blocks ([a6b716b](https://github.com/panva/jose/commit/a6b716b13859c76e4c1f7e33c60574514c6c2504))\n\n## [5.2.4](https://github.com/panva/jose/compare/v5.2.3...v5.2.4) (2024-04-07)\n\n\n### Refactor\n\n* use createLocalJWKSet instead of LocalJWKSet in createRemoteJWKSet ([a7c566c](https://github.com/panva/jose/commit/a7c566c61ccf3b62d2bd3a9e58a70e1d4d3c8b0c))\n\n## [5.2.3](https://github.com/panva/jose/compare/v5.2.2...v5.2.3) (2024-03-07)\n\n\n### Refactor\n\n* move iv generation and optional outputs around ([05c4351](https://github.com/panva/jose/commit/05c4351be3a356da2a0e882fbbd8006f2725ec7b))\n\n## [5.2.2](https://github.com/panva/jose/compare/v5.2.1...v5.2.2) (2024-02-11)\n\n\n### Fixes\n\n* **types:** iv and tag is optional in JSON serializations ([53019cd](https://github.com/panva/jose/commit/53019cd1fa3a4dc265d4868b9c626d4d6c832e86))\n\n## [5.2.1](https://github.com/panva/jose/compare/v5.2.0...v5.2.1) (2024-02-03)\n\n\n### Fixes\n\n* **build:** refactor export targets for browser, node cjs, and node esm builds ([50cbc65](https://github.com/panva/jose/commit/50cbc65e165ea27b4ed08ee7fc5a747a17d235da))\n\n## [5.2.0](https://github.com/panva/jose/compare/v5.1.3...v5.2.0) (2023-12-24)\n\n\n### Features\n\n* extend JWT NumericDate setter syntax ([ae363c3](https://github.com/panva/jose/commit/ae363c3c434fb040985f08da68ed02067d205cbe))\n\n## [5.1.3](https://github.com/panva/jose/compare/v5.1.2...v5.1.3) (2023-11-30)\n\n## [5.1.2](https://github.com/panva/jose/compare/v5.1.1...v5.1.2) (2023-11-27)\n\n\n### Fixes\n\n* do not mutate JWTVerifyOptions.requiredClaims ([1bf9cec](https://github.com/panva/jose/commit/1bf9cec024a4d01d989e15bb6e4b54e3940b4458)), closes [#610](https://github.com/panva/jose/issues/610)\n\n## [5.1.1](https://github.com/panva/jose/compare/v5.1.0...v5.1.1) (2023-11-14)\n\n\n### Refactor\n\n* deprecate the RSA1_5 JWE Algorithm ([f746da1](https://github.com/panva/jose/commit/f746da172b693eb417c4f75c8db6230cf213cd76))\n\n## [5.1.0](https://github.com/panva/jose/compare/v5.0.2...v5.1.0) (2023-11-03)\n\n\n### Features\n\n* add payload generics to jose.decodeJwt ([9de49e2](https://github.com/panva/jose/commit/9de49e26956a20cdb94472f10f83b20480613329)), closes [#604](https://github.com/panva/jose/issues/604)\n\n## [5.0.2](https://github.com/panva/jose/compare/v5.0.1...v5.0.2) (2023-11-02)\n\n\n### Fixes\n\n* **createRemoteJWKSet:** ensure a default user-agent header is present ([887dd3c](https://github.com/panva/jose/commit/887dd3cd05f34e06ce20ad00201599a5a469fbac)), closes [#600](https://github.com/panva/jose/issues/600)\n\n## [5.0.1](https://github.com/panva/jose/compare/v5.0.0...v5.0.1) (2023-10-25)\n\n\n### Fixes\n\n* also use ES2020 in the CDN bundles ([8c4d390](https://github.com/panva/jose/commit/8c4d3909db56f2d62cf2bf413e8343c0fdd2b92f))\n\n## [5.0.0](https://github.com/panva/jose/compare/v4.15.4...v5.0.0) (2023-10-25)\n\n\n### ⚠ BREAKING CHANGES\n\n* **Node.js:** return Uint8Array (not a Buffer) from base64url.decode\n* Browser distribution is now built using ES2020 as a target\n* Node.js distribution is now built using ES2022 as a target\n* **types:** jwtVerify and jwtDecrypt type argument for the resolved\nKeyLike type is now a second optional type argument following a type\nfor the JWT Claims Set (aka payload)\n* PBES2 Key Management Algorithms' use in decrypt\nfunctions now requires the use of the keyManagementAlgorithms option\nto explicitly opt-in for their use.\n* importJWK \"octAsKeyObject\" option was removed.\nimportJWK will no longer return CryptoKey or KeyObject for \"oct\" (octet\nsequence) JWK key types, it will instead always return a Uint8Array\nformed from the \"k\" (Key Value) Parameter regardless of the other JWK\nParameters that may be present.\n* End-Of-Life versions of Node.js as of October 2023 are\nno longer supported. Node.js 18, 20, and 21 and future releases are\nthe ones that remain supported.\n* The JWE \"zip\" (Compression Algorithm) Header Parameter\nis no longer supported by this JOSE implementation.\n\n### Features\n\n* add Date as valid input to timestamp setting functions ([bd830a4](https://github.com/panva/jose/commit/bd830a47979912d4c0775d01a05584c2aa9f0dcd))\n* default to an empty payload in JWT producing constructors ([98d6ca1](https://github.com/panva/jose/commit/98d6ca12c448697ed6342b1230b351eb5bfa0df8))\n* **types:** add optional Generics for JWT verify and decrypt ([61bd2a0](https://github.com/panva/jose/commit/61bd2a0adb638c1c2469459d78556a99cec697c7)), closes [#568](https://github.com/panva/jose/issues/568)\n\n\n### Reverts\n\n* Revert \"test: fix test under lts/erbium\" ([b64b6c7](https://github.com/panva/jose/commit/b64b6c731c3e2d0e6751e0221804af08d7015bfa))\n\n\n### Refactor\n\n* Browser distribution is now built using ES2020 as a target ([1836684](https://github.com/panva/jose/commit/18366840e1ae557b951fe921c5004b17ad56e972))\n* drop support for EOL Node.js versions ([b5aee54](https://github.com/panva/jose/commit/b5aee542fb5995dd29e012011f832ce8dfd24e29))\n* importJWK always returns a Uint8Array for symmetric key inputs ([163e1b0](https://github.com/panva/jose/commit/163e1b02ed5b64368110d750c9f5f5c3d247042d))\n* Node.js distribution is now built using ES2022 as a target ([239697a](https://github.com/panva/jose/commit/239697a17d048b8eb2120d29adff7f98edc0f26e))\n* **Node.js:** return Uint8Array (not a Buffer) from base64url.decode ([02d5182](https://github.com/panva/jose/commit/02d51827e24195d650cf83de100ae16cd8b0599e))\n* PBES2 Algorithms require explicit opt-in during verification ([e2da031](https://github.com/panva/jose/commit/e2da031381b7c5327ea9a0ccf58f059fa8af7e92))\n* remove support for JWE \"zip\" (Compression Algorithm) Header Parameter ([16998b1](https://github.com/panva/jose/commit/16998b15c75d90b64eb5b0fa0713cfdfa7896757))\n* **types:** rename type parameters for the KeyLike returns ([eddd400](https://github.com/panva/jose/commit/eddd400235e84e3d84c1a8471b01915a12d3d866))\n* update allow list error messages ([fe8114c](https://github.com/panva/jose/commit/fe8114c82646f2468857effb934f39dd7bc75902))\n\n## [4.15.4](https://github.com/panva/jose/compare/v4.15.3...v4.15.4) (2023-10-14)\n\n\n### Fixes\n\n* **types:** export GetKeyFunction ([#592](https://github.com/panva/jose/issues/592)) ([936c9df](https://github.com/panva/jose/commit/936c9dff2bc124dc5f64906a96f665a28e57392c)), closes [#591](https://github.com/panva/jose/issues/591)\n\n## [4.15.3](https://github.com/panva/jose/compare/v4.15.2...v4.15.3) (2023-10-11)\n\n## [4.15.2](https://github.com/panva/jose/compare/v4.15.1...v4.15.2) (2023-10-04)\n\n\n### Fixes\n\n* **build:** add a node target for jose-browser-runtime releases ([abb63d0](https://github.com/panva/jose/commit/abb63d0e8e7a55326dc343eec5f5eee9addc1dcf))\n\n## [4.15.1](https://github.com/panva/jose/compare/v4.15.0...v4.15.1) (2023-10-02)\n\n\n### Fixes\n\n* resolve missing types for the cryptoRuntime const ([1627965](https://github.com/panva/jose/commit/16279652a67133fba0db7c9879767f000a8f1662))\n\n## [4.15.0](https://github.com/panva/jose/compare/v4.14.6...v4.15.0) (2023-10-02)\n\n\n### Features\n\n* export the used crypto runtime as a constant ([0681dda](https://github.com/panva/jose/commit/0681dda1592a82c22a18981002b3763c502d0fc4))\n\n## [4.14.6](https://github.com/panva/jose/compare/v4.14.5...v4.14.6) (2023-09-04)\n\n\n### Fixes\n\n* **build:** publish bundle and umd files with jose-browser-runtime module ([62fcbcc](https://github.com/panva/jose/commit/62fcbcc2170db00f5bbfc817839523dbf970239f)), closes [#571](https://github.com/panva/jose/issues/571)\n\n## [4.14.5](https://github.com/panva/jose/compare/v4.14.4...v4.14.5) (2023-09-02)\n\n\n### Refactor\n\n* catch type error when decoding base64url signature ([#569](https://github.com/panva/jose/issues/569)) ([935e920](https://github.com/panva/jose/commit/935e920d29d242e0446d365b1e4f0449d144c23c))\n* catch type errors when decoding various base64url strings ([9024e87](https://github.com/panva/jose/commit/9024e870ece4ef121205dadc733c36d7978b97ab))\n\n## [4.14.4](https://github.com/panva/jose/compare/v4.14.3...v4.14.4) (2023-04-30)\n\n\n### Refactor\n\n* cleanup NODE-ED25519 workerd workarounds ([072e83d](https://github.com/panva/jose/commit/072e83de5bf3a15775b0bf25ef8afa8851b8862d))\n\n## [4.14.3](https://github.com/panva/jose/compare/v4.14.2...v4.14.3) (2023-04-27)\n\n\n### Reverts\n\n* Revert \"fix(types): headers and payloads may only be JSON values and primitives\" ([06d8101](https://github.com/panva/jose/commit/06d8101a5827a69bb25c2847b1a10d03f015db03)), closes [#534](https://github.com/panva/jose/issues/534)\n\n## [4.14.2](https://github.com/panva/jose/compare/v4.14.1...v4.14.2) (2023-04-26)\n\n\n### Fixes\n\n* **types:** headers and payloads may only be JSON values and primitives ([24f306e](https://github.com/panva/jose/commit/24f306e7f33485daaba1e250dfc97b5f621079ad))\n\n## [4.14.1](https://github.com/panva/jose/compare/v4.14.0...v4.14.1) (2023-04-20)\n\n## [4.14.0](https://github.com/panva/jose/compare/v4.13.2...v4.14.0) (2023-04-14)\n\n\n### Features\n\n* add requiredClaims JWT validation option ([eeea91d](https://github.com/panva/jose/commit/eeea91df48cadda84e4fdce6bbba7251ca7af83f))\n\n## [4.13.2](https://github.com/panva/jose/compare/v4.13.1...v4.13.2) (2023-04-12)\n\n\n### Refactor\n\n* src/util/decode_protected_header.ts ([5716725](https://github.com/panva/jose/commit/5716725d7eb6fa8a416638db9d448840f839f620))\n\n## [4.13.1](https://github.com/panva/jose/compare/v4.13.0...v4.13.1) (2023-03-02)\n\n\n### Fixes\n\n* **workerd:** avoid \"The script will never generate a response\" edge cases completely ([96a8c99](https://github.com/panva/jose/commit/96a8c99189f2399e9816ae1bca04b6d9cff93c26)), closes [#355](https://github.com/panva/jose/issues/355) [#509](https://github.com/panva/jose/issues/509)\n\n## [4.13.0](https://github.com/panva/jose/compare/v4.12.2...v4.13.0) (2023-02-27)\n\n\n### Features\n\n* **types:** allow generics to aid in CryptoKey or KeyObject narrowing of KeyLike ([6effa4d](https://github.com/panva/jose/commit/6effa4d35cfa984a5859d228f750e96af0c0a5e5))\n\n\n### Fixes\n\n* make jose.EmbeddedJWK arguments optional ([20610a9](https://github.com/panva/jose/commit/20610a930d337c25756de107d93b84ccc52707a3))\n\n## [4.12.2](https://github.com/panva/jose/compare/v4.12.1...v4.12.2) (2023-02-27)\n\n\n### Fixes\n\n* **types:** declare explicit return from EmbeddedJWK ([46934ac](https://github.com/panva/jose/commit/46934ac474ba0119976c5ac15cce4ea7bf50de8c))\n\n## [4.12.1](https://github.com/panva/jose/compare/v4.12.0...v4.12.1) (2023-02-27)\n\n\n### Refactor\n\n* clarify when alg is used and required on key imports ([19e525f](https://github.com/panva/jose/commit/19e525fdee04ba6281f70bd20523b878408aa7ee))\n* **node:** have node:crypto deal with x509 parsing ([45bb45d](https://github.com/panva/jose/commit/45bb45d42b6c96cbfcab7242d5cc366fb34481f1))\n\n## [4.12.0](https://github.com/panva/jose/compare/v4.11.4...v4.12.0) (2023-02-15)\n\n\n### Features\n\n* enable key iteration over JWKSMultipleMatchingKeys ([a278acd](https://github.com/panva/jose/commit/a278acdb0f458e555abdc1d048920e7da4fb7981))\n\n## [4.11.4](https://github.com/panva/jose/compare/v4.11.3...v4.11.4) (2023-02-07)\n\n\n### Fixes\n\n* **build:** ignore deno files in npm publishes ([b3d6a11](https://github.com/panva/jose/commit/b3d6a11bf0803c37e1e9d0368ccec1f1264eef74))\n\n## [4.11.3](https://github.com/panva/jose/compare/v4.11.2...v4.11.3) (2023-02-07)\n\n\n### Fixes\n\n* **CF Workers:** improve miniflare compat with different Node.js versions, get ready for future non-proprietary support ([3406b9f](https://github.com/panva/jose/commit/3406b9f73b1884b5db9c60675a68fe85794d48e0)), closes [#446](https://github.com/panva/jose/issues/446) [#495](https://github.com/panva/jose/issues/495) [#497](https://github.com/panva/jose/issues/497)\n\n## [4.11.2](https://github.com/panva/jose/compare/v4.11.1...v4.11.2) (2023-01-01)\n\n\n### Refactor\n\n* **node:** dry node version checks ([aff2f7c](https://github.com/panva/jose/commit/aff2f7c00f28b599ee72dd9f0a36c3783f1e195f))\n\n## [4.11.1](https://github.com/panva/jose/compare/v4.11.0...v4.11.1) (2022-11-22)\n\n## [4.11.0](https://github.com/panva/jose/compare/v4.10.4...v4.11.0) (2022-11-08)\n\n\n### Features\n\n* add bun as a supported runtime ([3a63631](https://github.com/panva/jose/commit/3a636318914866decd934d455d7c3789d304992c))\n\n\n### Fixes\n\n* respect JWK ext for symmetric keys ([20557fc](https://github.com/panva/jose/commit/20557fccf1ce0ebd7dd5d18cc33aa64d6f7b35ba))\n\n## [4.10.4](https://github.com/panva/jose/compare/v4.10.3...v4.10.4) (2022-10-28)\n\n\n### Fixes\n\n* typo in importPKSC8 error message ([#468](https://github.com/panva/jose/issues/468)) ([746bc64](https://github.com/panva/jose/commit/746bc64675636f2a09a6745e71cba8a2bdf3718f))\n* workaround for invalid use checks on CF Workers and Deno ([e4d04eb](https://github.com/panva/jose/commit/e4d04eb65f72041784d948eaa8432e4b64193729))\n\n## [4.10.3](https://github.com/panva/jose/compare/v4.10.2...v4.10.3) (2022-10-20)\n\n## [4.10.2](https://github.com/panva/jose/compare/v4.10.1...v4.10.2) (2022-10-20)\n\n## [4.10.1](https://github.com/panva/jose/compare/v4.10.0...v4.10.1) (2022-10-20)\n\n## [4.10.0](https://github.com/panva/jose/compare/v4.9.3...v4.10.0) (2022-09-27)\n\n\n### Features\n\n* Curve25519, and Curve448 support for WebCryptoAPI runtimes ([fea359a](https://github.com/panva/jose/commit/fea359a2055aa1b65170999a7f8e1bb23a3a1cb5))\n\n\n### Fixes\n\n* **importX509:** handle length encodings better ([47d0d77](https://github.com/panva/jose/commit/47d0d777a1ac90ff2ed0368fdab536db3d17aa8c)), closes [#459](https://github.com/panva/jose/issues/459)\n\n## [4.9.3](https://github.com/panva/jose/compare/v4.9.2...v4.9.3) (2022-09-15)\n\n\n### Refactor\n\n* update CEK length validation error message ([81a92a9](https://github.com/panva/jose/commit/81a92a9a9803022b82ea67577bde3fc0da3ecc6f))\n* update key input validation error messages ([2eac34a](https://github.com/panva/jose/commit/2eac34aa8f02c800a5f0b944e03fbe681c962b9c))\n* update keylike description for WinterCG ([6741679](https://github.com/panva/jose/commit/6741679936acf78f00c6effd559b4698cc92f123))\n\n## [4.9.2](https://github.com/panva/jose/compare/v4.9.1...v4.9.2) (2022-09-01)\n\n\n### Fixes\n\n* limit default PBES2 alg's computational expense ([03d6d01](https://github.com/panva/jose/commit/03d6d013bf6e070e85adfe5731f526978e3e8e4d))\n\n## [4.9.1](https://github.com/panva/jose/compare/v4.9.0...v4.9.1) (2022-08-29)\n\n\n### Fixes\n\n* **deno:** add a Deno package entrypoint ([9f3c459](https://github.com/panva/jose/commit/9f3c459e30b71eec54163d500edb59f5c72bf7c9))\n\n## [4.9.0](https://github.com/panva/jose/compare/v4.8.3...v4.9.0) (2022-08-17)\n\n\n### Features\n\n* add support for RFC 9278 - JWK Thumbprint URI ([d06ce65](https://github.com/panva/jose/commit/d06ce654666c5f584716f39843534118407c14e0))\n\n\n### Refactor\n\n* consume some base64url decode errors ([#436](https://github.com/panva/jose/issues/436)) ([caaf2c3](https://github.com/panva/jose/commit/caaf2c38dc51209d7adc493029f416c61759b1b1))\n* unify JOSENotSupported throw on key export ([fe5d093](https://github.com/panva/jose/commit/fe5d093bf74b812ecd3ee92d40dd02619e88e06c))\n\n## [4.8.3](https://github.com/panva/jose/compare/v4.8.1...v4.8.3) (2022-06-29)\n\n## [4.8.1](https://github.com/panva/jose/compare/v4.8.0...v4.8.1) (2022-05-02)\n\n\n### Fixes\n\n* **typescript:** add types export for nodenext module resolution ([#406](https://github.com/panva/jose/issues/406)) ([5a6d8f0](https://github.com/panva/jose/commit/5a6d8f0a2a3283bd1e832f1e71906d70f74c1262))\n\n## [4.8.0](https://github.com/panva/jose/compare/v4.7.0...v4.8.0) (2022-04-26)\n\n\n### Features\n\n* add \"worker\" export in package.json ([#400](https://github.com/panva/jose/issues/400)) ([c58c80a](https://github.com/panva/jose/commit/c58c80ae98b7a55b3b95e72438040983ae9a23de))\n* optional headers options for createRemoteJWKSet ([#397](https://github.com/panva/jose/issues/397)) ([b4612f5](https://github.com/panva/jose/commit/b4612f5d256b773ab7a1144ac839bdf0f8ccff53))\n\n## [4.7.0](https://github.com/panva/jose/compare/v4.6.2...v4.7.0) (2022-04-21)\n\n\n### Features\n\n* add createRemoteJWKSet cacheMaxAge option ([5017d95](https://github.com/panva/jose/commit/5017d95764b3aca551631c1a2fbe7cc40cbb6055)), closes [#394](https://github.com/panva/jose/issues/394)\n\n## [4.6.2](https://github.com/panva/jose/compare/v4.6.1...v4.6.2) (2022-04-19)\n\n\n### Fixes\n\n* dont check JWT iat is in the past unless maxTokenAge is used ([96d85c7](https://github.com/panva/jose/commit/96d85c70033d2249de41ed07d97ed6843c15eb2a))\n\n## [4.6.1](https://github.com/panva/jose/compare/v4.6.0...v4.6.1) (2022-04-11)\n\n## [4.6.0](https://github.com/panva/jose/compare/v4.5.3...v4.6.0) (2022-03-06)\n\n\n### Features\n\n* mark APIs and parameters that can lead to footguns as deprecated ([0ddbcc6](https://github.com/panva/jose/commit/0ddbcc6725ecb2d68efdaf0951cec4db31cc9b16))\n* **types:** include JSDoc in the types ([74187a9](https://github.com/panva/jose/commit/74187a9aa97cac70c42035949dd847177025af7c))\n\n## [4.5.3](https://github.com/panva/jose/compare/v4.5.2...v4.5.3) (2022-03-05)\n\n\n### Fixes\n\n* **web api runtime:** rely on default fetch init values ([df6d966](https://github.com/panva/jose/commit/df6d96651d4ddeeb4a9b05bd2d778bd58528dad2))\n\n## [4.5.2](https://github.com/panva/jose/compare/v4.5.1...v4.5.2) (2022-03-04)\n\n\n### Fixes\n\n* decrypting empty ciphertext compact JWEs ([#374](https://github.com/panva/jose/issues/374)) ([95fe597](https://github.com/panva/jose/commit/95fe59791dab9b31203f7a4ec5f4b44633d9b74f))\n\n## [4.5.1](https://github.com/panva/jose/compare/v4.5.0...v4.5.1) (2022-02-22)\n\n\n### Fixes\n\n* **typescript:** allow synchronous get key functions ([7c99153](https://github.com/panva/jose/commit/7c99153a9e8ae45a35de7eff45fcf6e60e1b088b))\n\n## [4.5.0](https://github.com/panva/jose/compare/v4.4.0...v4.5.0) (2022-02-07)\n\n\n### Features\n\n* add jose.decodeJwt utility ([3d2a2b8](https://github.com/panva/jose/commit/3d2a2b8eee18c9b60debbfae284b2bc3d2947dd2))\n\n\n### Fixes\n\n* concurrent fetch await in cloudflare ([e44cd18](https://github.com/panva/jose/commit/e44cd18ea4cf8af173f874ca3a847fc315eee592)), closes [#355](https://github.com/panva/jose/issues/355)\n\n## [4.4.0](https://github.com/panva/jose/compare/v4.3.9...v4.4.0) (2022-01-24)\n\n\n### Features\n\n* add createLocalJWKSet, resolver to verify using a local JWKSet ([bd7bf37](https://github.com/panva/jose/commit/bd7bf3789c146d765bbee2db0c93ba035020b24c))\n\n## [4.3.9](https://github.com/panva/jose/compare/v4.3.8...v4.3.9) (2022-01-22)\n\n\n### Fixes\n\n* only add y to the epk header parameter when EC keys are used ([dd6775e](https://github.com/panva/jose/commit/dd6775eed00b60c14b7038ddec85c8bb3cf05781)), closes [#348](https://github.com/panva/jose/issues/348)\n\n## [4.3.8](https://github.com/panva/jose/compare/v4.3.7...v4.3.8) (2022-01-09)\n\n## [4.3.7](https://github.com/panva/jose/compare/v4.3.6...v4.3.7) (2021-11-18)\n\n\n### Fixes\n\n* **typescript:** b64: true is fine to use in JWT, its useless, but allowed ([#324](https://github.com/panva/jose/issues/324)) ([ee401c9](https://github.com/panva/jose/commit/ee401c9e0f23f10ff5c0484798cb0cb3e9074b84))\n\n## [4.3.6](https://github.com/panva/jose/compare/v4.3.5...v4.3.6) (2021-11-16)\n\n\n### Fixes\n\n* **electron:** rsa-pss keys are never supported ([188c1f7](https://github.com/panva/jose/commit/188c1f709002302da99105cfc8fc6863a95761d9))\n\n## [4.3.5](https://github.com/panva/jose/compare/v4.3.4...v4.3.5) (2021-11-12)\n\n\n### Fixes\n\n* **typescript:** b64 header regression ([#324](https://github.com/panva/jose/issues/324)) ([9da0a7f](https://github.com/panva/jose/commit/9da0a7f49cf763314748eb01303320ce5af69762))\n\n## [4.3.4](https://github.com/panva/jose/compare/v4.3.3...v4.3.4) (2021-11-12)\n\n\n### Fixes\n\n* Compact JWS verification handles a zero-length payload string ([7c70e7b](https://github.com/panva/jose/commit/7c70e7b9700886dfad8e7555b909da8e079c88da))\n\n## [4.3.3](https://github.com/panva/jose/compare/v4.3.2...v4.3.3) (2021-11-11)\n\n\n### Fixes\n\n* **typescript:** apply updated compact and jwt headers to compact/jwt verify and decrypt results ([0c1946c](https://github.com/panva/jose/commit/0c1946c3e2a95e082b9a9095bf035756d8f17730))\n\n## [4.3.2](https://github.com/panva/jose/compare/v4.3.0...v4.3.2) (2021-11-11)\n\n\n### Fixes\n\n* createRemoteJWKSet handles all JWS syntaxes ([aaba8f3](https://github.com/panva/jose/commit/aaba8f3000b76b41733567367b9000348a839c17))\n* **typescript:** Compact JWS Header Parameters has alg and enc as required ([0fa87af](https://github.com/panva/jose/commit/0fa87af64b8e9f0f0cb68264f4dc22cc985acf91))\n* **typescript:** Compact JWS Header Parameters has alg as required ([c7fabd0](https://github.com/panva/jose/commit/c7fabd0f012513f3c9161b0f59befae1d7430e16))\n* **typescript:** Signed JWT Header Parameters has alg as required and b64 as never ([79cbd82](https://github.com/panva/jose/commit/79cbd82d3dd36f9ef87e4d306d77d9694a1c5836))\n\n## [4.3.0](https://github.com/panva/jose/compare/v4.2.1...v4.3.0) (2021-11-11)\n\n\n### Features\n\n* add GeneralSign signature and GeneralEncrypt recipient builder chaining ([cfc93f5](https://github.com/panva/jose/commit/cfc93f5daf4729a189ef5caabae4a9ec9ad45378))\n\n## [4.2.1](https://github.com/panva/jose/compare/v4.2.0...v4.2.1) (2021-11-09)\n\n\n### Fixes\n\n* **node:** dont mention CryptoKey in versions without webcrypto ([401cabf](https://github.com/panva/jose/commit/401cabf97419768cea1d685dc73d933fa38d6c26))\n\n## [4.2.0](https://github.com/panva/jose/compare/v4.1.5...v4.2.0) (2021-11-08)\n\n\n### Features\n\n* General JWE Encryption ([94eca81](https://github.com/panva/jose/commit/94eca816872527074d2a591a983ee6c5d64da30c))\n\n## [4.1.5](https://github.com/panva/jose/compare/v4.1.4...v4.1.5) (2021-11-05)\n\n\n### Fixes\n\n* importX509 certificate values that do not include a version number ([51a18b6](https://github.com/panva/jose/commit/51a18b675a771ed573047398f79cd6f70d8f9fec)), closes [#308](https://github.com/panva/jose/issues/308)\n\n## [4.1.4](https://github.com/panva/jose/compare/v4.1.3...v4.1.4) (2021-11-01)\n\n\n### Fixes\n\n* allow shorter HMAC secrets ([57126f1](https://github.com/panva/jose/commit/57126f1806493a2782647610c2a6b5d20ea3e516))\n\n## [4.1.3](https://github.com/panva/jose/compare/v4.1.2...v4.1.3) (2021-11-01)\n\n\n### Fixes\n\n* **edge-functions:** don't use globalThis ([3952030](https://github.com/panva/jose/commit/39520302d078da2273b5a24f8254f6c221195c63))\n\n## [4.1.2](https://github.com/panva/jose/compare/v4.1.1...v4.1.2) (2021-10-25)\n\n\n### Fixes\n\n* **build:** ensure cjs/esm specific packages have the right main entry ([2f4526a](https://github.com/panva/jose/commit/2f4526a22b9bd62727bdd825e326ef79695c8ea3))\n\n## [4.1.1](https://github.com/panva/jose/compare/v4.1.0...v4.1.1) (2021-10-21)\n\n\n### Fixes\n\n* **typescript:** work around potentially missing global URL from DOM lib ([7ed731c](https://github.com/panva/jose/commit/7ed731c567db6e64f0fbd618efe7e48d812af0c6)), closes [#295](https://github.com/panva/jose/issues/295)\n\n## [4.1.0](https://github.com/panva/jose/compare/v4.0.4...v4.1.0) (2021-10-18)\n\n\n### Features\n\n* **web:** publish umd and bundle files to cdnjs.com ([3b3100a](https://github.com/panva/jose/commit/3b3100a8f115db5fb7c56482a0c5cf4814e0f838))\n\n## [4.0.4](https://github.com/panva/jose/compare/v4.0.3...v4.0.4) (2021-10-17)\n\n\n### Fixes\n\n* **web:** check Uint8Array CEK lengths, refactor for better tree-shaking ([e8299f2](https://github.com/panva/jose/commit/e8299f246b1dbf1665d8f1ed141b9bde34684293))\n\n## [4.0.3](https://github.com/panva/jose/compare/v4.0.2...v4.0.3) (2021-10-16)\n\n\n### Fixes\n\n* **web:** checking cryptokey applicability early ([89dc2aa](https://github.com/panva/jose/commit/89dc2aab99d831e922ba865eccfb29b8229ed767))\n\n## [4.0.2](https://github.com/panva/jose/compare/v4.0.1...v4.0.2) (2021-10-15)\n\n\n### Fixes\n\n* **typescript:** export ProduceJWT ([#285](https://github.com/panva/jose/issues/285)) ([2b8738e](https://github.com/panva/jose/commit/2b8738e38a4286c9a1411e3aef3159f61427317c))\n\n## [4.0.1](https://github.com/panva/jose/compare/v4.0.0...v4.0.1) (2021-10-14)\n\n\n### Fixes\n\n* **typescript:** re-export all types from index.d.ts ([d68f104](https://github.com/panva/jose/commit/d68f104d5895f639812b3317696a4616c3e5fb59))\n\n## [4.0.0](https://github.com/panva/jose/compare/v3.20.3...v4.0.0) (2021-10-14)\n\n\n### ⚠ BREAKING CHANGES\n\n* All module named exports have moved from subpaths to\njust \"jose\". For example, `import { jwtVerify } from 'jose/jwt/verify'`\nis now just `import { jwtVerify } from 'jose'`.\n* All submodule default exports and named have been\nremoved in favour of just \"jose\" named exports.\n* **typescript:** remove repeated type re-exports\n* The undocumented `jose/util/random` was removed.\n* The `jose/jwk/thumbprint` named export\nis renamed to `calculateJwkThumbprint`, now\n`import { calculateJwkThumbprint } from 'jose'`\n* The deprecated `jose/jwk/parse` module was\nremoved, use `import { importJWK } from 'jose'` instead.\n* The deprecated `jose/jwk/from_key_like` module was\nremoved, use `import { exportJWK } from 'jose'` instead.\n\n### Refactor\n\n* redo exports to support broader tooling ([dd2cf9e](https://github.com/panva/jose/commit/dd2cf9ed2d89488de6dc4536f721887ffc9bb34f))\n* remove util/random ([914e47f](https://github.com/panva/jose/commit/914e47fc9b6c207fd7e3469b1c3fac40f7a81031))\n* removed the deprecated jwk/from_key_like module ([ec1d0e7](https://github.com/panva/jose/commit/ec1d0e72fe39ec2bccc28e46b5bce2dc17711134))\n* removed the deprecated jwk/parse module ([8d3cc3b](https://github.com/panva/jose/commit/8d3cc3bb46e7e87e6511859dce58a651811ca551))\n* rename calculateThumprint to calculateJwkThumbprint ([5afb713](https://github.com/panva/jose/commit/5afb713fbb99e6c884bb3b1c68ae2cf490e54595))\n* **typescript:** remove repeated type re-exports ([3e137d2](https://github.com/panva/jose/commit/3e137d2427035d18397825074c2ee1e5db97515b))\n\n## [3.20.3](https://github.com/panva/jose/compare/v3.20.2...v3.20.3) (2021-10-14)\n\n\n### Fixes\n\n* remove clutter when tree shaking browser dist ([73ba370](https://github.com/panva/jose/commit/73ba3708d45e32215c76f17d9982b0f4e20b7f08))\n* **typescript:** JWTExpired error TS2417 ([373e0e4](https://github.com/panva/jose/commit/373e0e4b22fb48cefcf14385a19c5ea6a57a849e))\n\n## [3.20.2](https://github.com/panva/jose/compare/v3.20.1...v3.20.2) (2021-10-13)\n\n\n### Fixes\n\n* allow tree-shaking of errors ([0824301](https://github.com/panva/jose/commit/08243010d922c36d22002e35299ec5710654c695))\n\n## [3.20.1](https://github.com/panva/jose/compare/v3.20.0...v3.20.1) (2021-10-06)\n\n\n### Fixes\n\n* **typescript:** PEM import functions always resolve a KeyLike, never a Uint8Array ([8ef3a8e](https://github.com/panva/jose/commit/8ef3a8ebb78b592e664102cb593542ae6259d72a))\n\n## [3.20.0](https://github.com/panva/jose/compare/v3.19.0...v3.20.0) (2021-10-06)\n\n\n### Features\n\n* improve key input type errors, remove dependency on @types/node ([a13eb04](https://github.com/panva/jose/commit/a13eb045d86d96e56f7a250cdc808f8c5aa0e62a))\n\n\n### Fixes\n\n* proper createRemoteJWKSet timeoutDuration handling ([efa1619](https://github.com/panva/jose/commit/efa16195173f9f66b21d4f41039caaad0ccfa92a)), closes [#277](https://github.com/panva/jose/issues/277)\n\n## [3.19.0](https://github.com/panva/jose/compare/v3.18.0...v3.19.0) (2021-09-26)\n\n\n### Features\n\n* return resolved key when verify and decrypt resolve functions are used ([49fb62c](https://github.com/panva/jose/commit/49fb62cb96cd9afc854f5102313f16e27c0eb2b4))\n\n## [3.18.0](https://github.com/panva/jose/compare/v3.17.0...v3.18.0) (2021-09-22)\n\n\n### Features\n\n* add X.509/SPKI/PKCS8 key import and SPKI/PKCS8 export functions ([a2af0f4](https://github.com/panva/jose/commit/a2af0f45fe47b3d73178ab00c18e49fccd2b1432))\n\n## [3.17.0](https://github.com/panva/jose/compare/v3.16.1...v3.17.0) (2021-09-10)\n\n\n### Features\n\n* **cloudflare workers:** add support for EdDSA using Ed25519 ([0967369](https://github.com/panva/jose/commit/09673694027ffc4961c211c12e0b7eb2ac9966f3))\n\n## [3.16.1](https://github.com/panva/jose/compare/v3.16.0...v3.16.1) (2021-09-08)\n\n\n### Fixes\n\n* guard Sign payloads and Encrypt plaintext argument types ([10a18f2](https://github.com/panva/jose/commit/10a18f28a0f845e91579afab3573730c9b1ae478))\n\n## [3.16.0](https://github.com/panva/jose/compare/v3.15.5...v3.16.0) (2021-09-07)\n\n\n### Features\n\n* **node:** support rsa-pss keys in Node.js >= 16.9.0 for sign/verify ([0b112cf](https://github.com/panva/jose/commit/0b112cf63ed2a859806531853c37486485740f9c))\n\n## [3.15.5](https://github.com/panva/jose/compare/v3.15.4...v3.15.5) (2021-09-02)\n\n\n### Fixes\n\n* omit some fetch options when running in Cloudflare Workers env ([ced065a](https://github.com/panva/jose/commit/ced065aa9754c625ea88a598025962503e078ae9)), closes [#255](https://github.com/panva/jose/issues/255)\n\n## [3.15.4](https://github.com/panva/jose/compare/v3.15.3...v3.15.4) (2021-08-20)\n\n\n### Fixes\n\n* **deno:** ignore incomplete webcrypto api type errors ([c5f2262](https://github.com/panva/jose/commit/c5f226290ead93b7f43f664fc05c5fec90f38be8))\n* **typescript:** generateKeyPair never returns Uint8Array ([73adc01](https://github.com/panva/jose/commit/73adc014ad9827067637153a97f230bfdd72cb9b))\n\n## [3.15.3](https://github.com/panva/jose/compare/v3.15.2...v3.15.3) (2021-08-20)\n\n\n### Fixes\n\n* **typescript:** GeneralJWSInput and GeneralJWS omit ([bc0b42f](https://github.com/panva/jose/commit/bc0b42f0f58e802721910ac1bc4d62eb704910ff))\n\n## [3.15.2](https://github.com/panva/jose/compare/v3.15.1...v3.15.2) (2021-08-20)\n\n## [3.15.1](https://github.com/panva/jose/compare/v3.15.0...v3.15.1) (2021-08-20)\n\n\n### Fixes\n\n* **typescript:** remove file extensions from types/**/*.d.ts files ([0c432e5](https://github.com/panva/jose/commit/0c432e554e7b1f0382efefe44c0053a446c9dcc4)), closes [#222](https://github.com/panva/jose/issues/222)\n\n## [3.15.0](https://github.com/panva/jose/compare/v3.14.4...v3.15.0) (2021-08-20)\n\n\n### Features\n\n* experimental Deno build & publish ([5c7d265](https://github.com/panva/jose/commit/5c7d2656b6e5659a19c6cb3c4fed73e724fe2f6e))\n\n\n### Fixes\n\n* **typescript:** allow sign results to be passed to verify ([59aa96d](https://github.com/panva/jose/commit/59aa96d28dd259d9d8b03fcf37b5a703c5e36874))\n\n## [3.14.4](https://github.com/panva/jose/compare/v3.14.3...v3.14.4) (2021-08-16)\n\n\n### Fixes\n\n* throw JWEInvalid when jwe protected header is invalid ([991d435](https://github.com/panva/jose/commit/991d4350d0357ebad17080644c24bccec844c3b9))\n* throw JWSInvalid when jws protected header is invalid ([#244](https://github.com/panva/jose/issues/244)) ([1fc79aa](https://github.com/panva/jose/commit/1fc79aa8315fa25e28f63f1c5534d0630fc781dc))\n\n## [3.14.3](https://github.com/panva/jose/compare/v3.14.2...v3.14.3) (2021-07-21)\n\n\n### Fixes\n\n* **docs:** update doc links again ([26c4361](https://github.com/panva/jose/commit/26c4361c007e3bc7e6ee60b65f9535cecf447fe6))\n\n## [3.14.2](https://github.com/panva/jose/compare/v3.14.1...v3.14.2) (2021-07-21)\n\n\n### Fixes\n\n* **docs:** update doc links ([86f9134](https://github.com/panva/jose/commit/86f9134248a1746904f4c9f79ee404007ab68858))\n\n## [3.14.1](https://github.com/panva/jose/compare/v3.14.0...v3.14.1) (2021-07-21)\n\n\n### Fixes\n\n* **typescript:** export generate key pair result interface ([2b5cc28](https://github.com/panva/jose/commit/2b5cc28684bd9cd09de2f774d7326bffe61fe6ea))\n\n## [3.14.0](https://github.com/panva/jose/compare/v3.13.0...v3.14.0) (2021-07-02)\n\n\n### Features\n\n* add verbose key type error messages ([df56b94](https://github.com/panva/jose/commit/df56b942c64dfdbb14cb860a403742f25ec60b49))\n\n\n### Fixes\n\n* **typescript:** remove file extensions from .d.ts files ([e091f0f](https://github.com/panva/jose/commit/e091f0f24537541e350e803bd1e657348f428da2)), closes [#222](https://github.com/panva/jose/issues/222)\n* AES Key Wrap input type check ([b83821b](https://github.com/panva/jose/commit/b83821b2bf99fe2051d4d4d89fe4ff18a8559722))\n* guard SignJWT.prototype.sign() from missing protected header ([4103719](https://github.com/panva/jose/commit/4103719c24d1811306acf7d5290ef15c5afddcfb)), closes [#221](https://github.com/panva/jose/issues/221)\n* **typescript:** add \"jku\" header to JoseHeaderParameters ([#220](https://github.com/panva/jose/issues/220)) ([72a72db](https://github.com/panva/jose/commit/72a72db7723e06994066d6ad154073387c5bc17c))\n\n## [3.13.0](https://github.com/panva/jose/compare/v3.12.3...v3.13.0) (2021-06-22)\n\n\n### Features\n\n* **typescript:** export consume module interface types ([#213](https://github.com/panva/jose/issues/213)) ([13fa3d8](https://github.com/panva/jose/commit/13fa3d8ae089b21dace0ea22782451ca77941600))\n\n## [3.12.3](https://github.com/panva/jose/compare/v3.12.2...v3.12.3) (2021-06-02)\n\n\n### Fixes\n\n* **browser:** remove the use of a node std-lib in decodeProtectedHeader ([d9d4a5f](https://github.com/panva/jose/commit/d9d4a5f2e88ca5172ff753a503bfbdb50522d094)), closes [#206](https://github.com/panva/jose/issues/206)\n\n## [3.12.2](https://github.com/panva/jose/compare/v3.12.1...v3.12.2) (2021-05-19)\n\n\n### Performance\n\n* **node:** use util.types.is* helpers when available ([d36311d](https://github.com/panva/jose/commit/d36311d5162b3500728937bf25bd2c756f8a33d6))\n\n## [3.12.1](https://github.com/panva/jose/compare/v3.12.0...v3.12.1) (2021-05-14)\n\n\n### Fixes\n\n* **browser:** avoid global-conflicting variable name fetch ([#199](https://github.com/panva/jose/issues/199)) ([b2c6273](https://github.com/panva/jose/commit/b2c6273eccad5e34cbe0219c521c6453ba71e6c4))\n\n## [3.12.0](https://github.com/panva/jose/compare/v3.11.6...v3.12.0) (2021-05-12)\n\n\n### Features\n\n* **webcrypto:** allow generate* modules extractable: false override ([afae428](https://github.com/panva/jose/commit/afae428f39eb920297ef474878d4266172d9a015))\n\n## [3.11.6](https://github.com/panva/jose/compare/v3.11.5...v3.11.6) (2021-04-30)\n\n\n### Fixes\n\n* swallow promisified crypto.verify errors ([d512ede](https://github.com/panva/jose/commit/d512ede0730155051707d60ae8c69ba0492d858f))\n\n## [3.11.5](https://github.com/panva/jose/compare/v3.11.4...v3.11.5) (2021-04-13)\n\n\n### Fixes\n\n* isObject helper in different vm contexts or jest re-assigned globals ([7819df7](https://github.com/panva/jose/commit/7819df73ebf6391377ef3e7623948d8329ac47f5)), closes [#178](https://github.com/panva/jose/issues/178)\n\n## [3.11.4](https://github.com/panva/jose/compare/v3.11.3...v3.11.4) (2021-04-09)\n\n\n### Fixes\n\n* defer AES CBC w/ HMAC decryption after tag verification passes ([579485c](https://github.com/panva/jose/commit/579485cb806e9989643e32a66752d3235cd43f09))\n\n## [3.11.3](https://github.com/panva/jose/compare/v3.11.2...v3.11.3) (2021-04-01)\n\n\n### Fixes\n\n* **node:** check CryptoKey algorithm & usage before exporting KeyObject ([dab4b2f](https://github.com/panva/jose/commit/dab4b2f03efc5772773e66fdb757db5571deee4d))\n\n## [3.11.2](https://github.com/panva/jose/compare/v3.11.1...v3.11.2) (2021-03-30)\n\n\n### Fixes\n\n* assert KeyLike input types, change \"any\" types to \"unknown\" ([edb83a8](https://github.com/panva/jose/commit/edb83a846a880d316d77ace485641330dd0debb6))\n\n## [3.11.1](https://github.com/panva/jose/compare/v3.11.0...v3.11.1) (2021-03-26)\n\n\n### Fixes\n\n* **node:** crypto.verify callback invocation with a private keyobject ([d3d4acd](https://github.com/panva/jose/commit/d3d4acd8be612850999309ef7de86c549d5de9c0))\n\n## [3.11.0](https://github.com/panva/jose/compare/v3.10.0...v3.11.0) (2021-03-24)\n\n\n### Features\n\n* export error codes as static properties ([89d8003](https://github.com/panva/jose/commit/89d80038755be21228a3455a8feca396e76fbcf5)), closes [#170](https://github.com/panva/jose/issues/170)\n\n## [3.10.0](https://github.com/panva/jose/compare/v3.9.0...v3.10.0) (2021-03-18)\n\n\n### Features\n\n* **node:** use libuv threadpool to sign in node >= 15.12.0 ([cf5074e](https://github.com/panva/jose/commit/cf5074e7e1333728f7632ee6785cc52ef32711bf))\n* **node:** use libuv threadpool to verify in node >= 15.12.0 ([ae9a7f4](https://github.com/panva/jose/commit/ae9a7f4186da9675820dc2e77786b9ee3f7dd0d0))\n* **node:** use native JWK export in node >= 15.9.0 ([7f3cc44](https://github.com/panva/jose/commit/7f3cc44bd0508bf15c061500738473eeafdc32d1))\n* **node:** use native JWK import in node >= 15.12.0 ([f0c2a64](https://github.com/panva/jose/commit/f0c2a6472844c43a92a79ed90b51cc5133a2e22e))\n\n## [3.9.0](https://github.com/panva/jose/compare/v3.8.0...v3.9.0) (2021-03-15)\n\n\n### Features\n\n* add named exports for all modules ([5cba6b0](https://github.com/panva/jose/commit/5cba6b0fdddd24c2e48623d8aaf48640b3279a43))\n\n## [3.8.0](https://github.com/panva/jose/compare/v3.7.1...v3.8.0) (2021-03-12)\n\n\n### Features\n\n* publish alternative Node.js and Browser specific distributions ([7856dad](https://github.com/panva/jose/commit/7856dad1031845bfc3cadfdbe609d0f0154f19ce))\n\n## [3.7.1](https://github.com/panva/jose/compare/v3.7.0...v3.7.1) (2021-03-11)\n\n\n### Fixes\n\n* swallow invalid signature encoding errors ([e0adf49](https://github.com/panva/jose/commit/e0adf49e5789f9fc23afb1e2bd3e330e34b46b78))\n\n## [3.7.0](https://github.com/panva/jose/compare/v3.6.2...v3.7.0) (2021-03-02)\n\n\n### Features\n\n* electron >=12.0.0 is now supported (and tested on ci) ([8fffd3e](https://github.com/panva/jose/commit/8fffd3e2e1ec0c5f3517a779b42974a4c1beae27))\n\n\n### Fixes\n\n* **electron:** only call (de)cipher.setAAD() when aad is not empty ([a5a6c4d](https://github.com/panva/jose/commit/a5a6c4dc9f459b88de5f243cf1d4ea620def8d98))\n* **electron:** properly ASN.1 encode [0x00] when converting RSA JWKs ([433f020](https://github.com/panva/jose/commit/433f020246a9131f63705a3e1aa99492dac50947))\n\n## [3.6.2](https://github.com/panva/jose/compare/v3.6.1...v3.6.2) (2021-02-16)\n\n\n### Fixes\n\n* **typescript:** update maxTokenAge type and examples ([2c358e0](https://github.com/panva/jose/commit/2c358e0ea550f19896ccf43724ee8224aa04a664))\n\n## [3.6.1](https://github.com/panva/jose/compare/v3.6.0...v3.6.1) (2021-02-10)\n\n\n### Fixes\n\n* node runtime json fetch handles connection errors properly ([fc584b2](https://github.com/panva/jose/commit/fc584b2efd9a6e7bf2ac83c6fb0ddf96fb0ca6a5))\n\n## [3.6.0](https://github.com/panva/jose/compare/v3.5.4...v3.6.0) (2021-02-04)\n\n\n### Features\n\n* allow CryptoKey instances in a regular non-webcrypto node runtime ([e8d41a9](https://github.com/panva/jose/commit/e8d41a933582495c9a9b02d6ec38b46bef8795e1))\n\n## [3.5.4](https://github.com/panva/jose/compare/v3.5.3...v3.5.4) (2021-01-26)\n\n\n### Fixes\n\n* export package.json ([8c29107](https://github.com/panva/jose/commit/8c29107aea26a54869d8adadceaf0bbf70fb18cd)), closes [#157](https://github.com/panva/jose/issues/157)\n\n## [3.5.3](https://github.com/panva/jose/compare/v3.5.2...v3.5.3) (2021-01-20)\n\n\n### Fixes\n\n* workaround downstream dependency issues messing with http ([2e58005](https://github.com/panva/jose/commit/2e5800535ab72ab35f3abfaab7493163d8b0494e)), closes [#154](https://github.com/panva/jose/issues/154)\n\n## [3.5.2](https://github.com/panva/jose/compare/v3.5.1...v3.5.2) (2021-01-18)\n\n\n### Performance\n\n* use 'base64url' encoding when available in Node.js runtime ([808f06c](https://github.com/panva/jose/commit/808f06cd08b10cf53343afb35802cc6e5b95ea20))\n* use KeyObject.prototype asymmetricKeyDetails when available ([ad88ee2](https://github.com/panva/jose/commit/ad88ee2cd5bcaee3c3e5ec79735c8172ae2725be))\n\n## [3.5.1](https://github.com/panva/jose/compare/v3.5.0...v3.5.1) (2021-01-10)\n\n\n### Fixes\n\n* workaround for RangeError in browser runtime base64url ([ed32b0d](https://github.com/panva/jose/commit/ed32b0d46ee570e405e0d88b43aecd8ef6fea129))\n\n## [3.5.0](https://github.com/panva/jose/compare/v3.4.0...v3.5.0) (2020-12-17)\n\n\n### Features\n\n* added JWE General JSON Serialization decryption ([16dea9e](https://github.com/panva/jose/commit/16dea9ec7d6179471f794a3463bba0c6e77295ff))\n\n## [3.4.0](https://github.com/panva/jose/compare/v3.3.2...v3.4.0) (2020-12-16)\n\n\n### Features\n\n* added JWS General JSON Serialization signing ([6fb862c](https://github.com/panva/jose/commit/6fb862cf12d34b7dc5077d1872ad29eeac27d21e)), closes [#129](https://github.com/panva/jose/issues/129)\n* added JWS General JSON Serialization verification ([55b7781](https://github.com/panva/jose/commit/55b77810d03a1f7e38e13bec384dece08b74b206)), closes [#129](https://github.com/panva/jose/issues/129)\n* added utility function for decoding token's protected header ([fa29d68](https://github.com/panva/jose/commit/fa29d68cfdf0922c7e4dac24eb50161d1eab28d4))\n\n## [3.3.2](https://github.com/panva/jose/compare/v3.3.1...v3.3.2) (2020-12-14)\n\n\n### Fixes\n\n* **typescript:** ref dom lib via triple-slash to fix some compile issues ([175f273](https://github.com/panva/jose/commit/175f273819785c29b9ad822dcb5d70073523f504)), closes [#126](https://github.com/panva/jose/issues/126)\n\n## [3.3.1](https://github.com/panva/jose/compare/v3.3.0...v3.3.1) (2020-12-06)\n\n\n### Fixes\n\n* botched v3.3.0 release ([1c3e116](https://github.com/panva/jose/commit/1c3e116976c997f205b917405f010b568d1bd3b9))\n\n## [3.3.0](https://github.com/panva/jose/compare/v3.2.0...v3.3.0) (2020-12-06)\n\n\n### Features\n\n* support recognizing proprietary `crit` header parameters ([5163116](https://github.com/panva/jose/commit/5163116ca1c091871ed0c601c9fbc1dbe94599cd)), closes [#123](https://github.com/panva/jose/issues/123)\n\n\n### Fixes\n\n* reject JWTs with b64: false ([691b44a](https://github.com/panva/jose/commit/691b44ad4717c82a06539facfedff48fa0e9c6a9))\n\n## [3.2.0](https://github.com/panva/jose/compare/v3.1.3...v3.2.0) (2020-12-02)\n\n\n### Features\n\n* allow specifying modulusLength when generating RSA Key Pairs ([5f7a0e9](https://github.com/panva/jose/commit/5f7a0e9055256bce4786a53711bcf14cf59fa8f1)), closes [#121](https://github.com/panva/jose/issues/121)\n\n## [3.1.3](https://github.com/panva/jose/compare/v3.1.2...v3.1.3) (2020-11-26)\n\n\n### Fixes\n\n* **typescript:** refactored how types are published ([2937363](https://github.com/panva/jose/commit/29373633bc540ff1e7bfe8fb3e5c5b391e79c2d9)), closes [#119](https://github.com/panva/jose/issues/119)\n\n## [3.1.2](https://github.com/panva/jose/compare/v3.1.1...v3.1.2) (2020-11-24)\n\n\n### Fixes\n\n* handle globalThis undefined in legacy browsers ([b83c59b](https://github.com/panva/jose/commit/b83c59bb43ad14ac932cd0c662f7dfc2c4c62753))\n\n## [3.1.1](https://github.com/panva/jose/compare/v3.1.0...v3.1.1) (2020-11-24)\n\n\n### Fixes\n\n* global detection in a browser worker runtime ([56ff8fa](https://github.com/panva/jose/commit/56ff8fa65aa045411c6c6a67d80b67c1099576a0))\n\n## [3.1.0](https://github.com/panva/jose/compare/v3.0.2...v3.1.0) (2020-11-22)\n\n\n### Features\n\n* added \"KeyLike to JWK\" module ([7a8418e](https://github.com/panva/jose/commit/7a8418eadd68b645fb7edf78873a35980ea8e41d)), closes [#109](https://github.com/panva/jose/issues/109)\n* allow compact verify/decrypt tokens to be uint8array encoded ([e39c3db](https://github.com/panva/jose/commit/e39c3dba75e5ae70697e6a4f93096c492a265c07))\n* allow http.Agent and https.Agent passed in remote JWK Set ([38494a8](https://github.com/panva/jose/commit/38494a88828a8df2015efa78ca29c1a6317a3a50))\n\n## [3.0.2](https://github.com/panva/jose/compare/v3.0.1...v3.0.2) (2020-11-15)\n\n\n### Fixes\n\n* **build:** publish esm submodules ([7b6364f](https://github.com/panva/jose/commit/7b6364f26f7654368c9e33af58043ee40e77ec77)), closes [#104](https://github.com/panva/jose/issues/104)\n\n## [3.0.1](https://github.com/panva/jose/compare/v3.0.0...v3.0.1) (2020-11-15)\n\n\n### Fixes\n\n* **typescript:** fix compiling by adding .d.ts files for runtime modules ([d9cb573](https://github.com/panva/jose/commit/d9cb5734d779df26c3e717a9f4f23d18b856dc5f))\n\n## [3.0.0](https://github.com/panva/jose/compare/v2.0.3...v3.0.0) (2020-11-14)\n\n\n### ⚠ BREAKING CHANGES\n\n* Revised, Promise-based API\n* No dependencies\n* Browser support (using [Web Cryptography API](https://www.w3.org/TR/WebCryptoAPI/))\n* Support for verification using a remote JWKS endpoint\n\n### Features\n\n* Revised API, No dependencies, Browser Support, Promises ([357fe0b](https://github.com/panva/jose/commit/357fe0b964903e8c84ab49f0f27ddf0447d44c84))\n\n## [2.0.3](https://github.com/panva/jose/compare/v2.0.2...v2.0.3) (2020-10-29)\n\n\n### Fixes\n\n* allow stubbing of the JWT.decode function ([6c3b92f](https://github.com/panva/jose/commit/6c3b92f4394a5d7092d7336922eda61e311e6f8c))\n\n## [2.0.2](https://github.com/panva/jose/compare/v2.0.1...v2.0.2) (2020-09-14)\n\n\n### Fixes\n\n* **esm:** include esm files in the published package ([1956746](https://github.com/panva/jose/commit/1956746df6542c00bc33af750f93394805b5d603))\n\n## [2.0.1](https://github.com/panva/jose/compare/v2.0.0...v2.0.1) (2020-09-10)\n\n\n### Fixes\n\n* allow plugins such as jose-chacha to work in newer node runtime ([30f1dc2](https://github.com/panva/jose/commit/30f1dc2c41e5554d322167b84b610a99bf5e69c5))\n\n## [2.0.0](https://github.com/panva/jose/compare/v1.28.0...v2.0.0) (2020-09-08)\n\n\n### ⚠ BREAKING CHANGES\n\n* the `JWE.decrypt` option `algorithms` was removed and\nreplaced with contentEncryptionAlgorithms (handles `enc` allowlist) and\nkeyManagementAlgorithms (handles `alg` allowlist)\n* the `JWT.verify` profile option was removed, use e.g.\n`JWT.IdToken.verify` instead.\n* removed the `maxAuthAge` `JWT.verify` option, this\noption is now only present at the specific JWT profile APIs where the\n`auth_time` property applies.\n* removed the `nonce` `JWT.verify` option, this\noption is now only present at the specific JWT profile APIs where the\n`nonce` property applies.\n* the `acr`, `amr`, `nonce` and `azp` claim value types\nwill only be checked when verifying a specific JWT profile using its\ndedicated API.\n* using the draft implementing APIs will emit a one-time\nwarning per process using `process.emitWarning`\n* `JWT.sign` function options no longer accept a `nonce`\nproperty. To create a JWT with a `nonce` just pass the value to the\npayload.\n* due to added ESM module support Node.js version with\nESM implementation bugs are no longer supported, this only affects early\nv13.x versions. The resulting Node.js semver range is\n`>=10.13.0 < 13 || >=13.7.0`\n* deprecated method `JWK.importKey` was removed\n* deprecated method `JWKS.KeyStore.fromJWKS` was removed\n* the use of unregistered curve name P-256K for secp256k1\nwas removed\n* jose.JWE.Encrypt constructor aad and unprotectedHeader\narguments swapped places\n* jose.JWE.encrypt.flattened header (unprotectedHeader)\nand aad arguments swapped places\n* jose.JWE.encrypt.general header (unprotectedHeader)\nand aad arguments swapped places\n* JWS.verify returned payloads are now always buffers\n* JWS.verify options `encoding` and `parse` were removed\n\n### Features\n\n* added support for ESM (ECMAScript modules) ([1aa9035](https://github.com/panva/jose/commit/1aa9035552bbcb34b95e092d0f082cc6d94465ab))\n* decrypt allowlists for both key management and content encryption ([30e5c46](https://github.com/panva/jose/commit/30e5c46ecf00a498e65a551ced88bc897531c2a4))\n\n\n### Fixes\n\n* **typescript:** allow Buffer when verifying detached signature ([cadbd04](https://github.com/panva/jose/commit/cadbd047ca953d6d8171439f2efd7bb98a5d8e73))\n* **typescript:** properly type all decode/verify/decrypt fn options ([4c23bd6](https://github.com/panva/jose/commit/4c23bd65fe6fa634726a5eb73c6d590f7348a97e))\n\n\n### Refactor\n\n* encrypt APIs unprotectedHeader and aad arguments swapped ([70bd4ae](https://github.com/panva/jose/commit/70bd4ae6b2e6ba94bbe0b3dc1a17b2990af3a18b))\n* move JWT profile specifics outside of generic JWT ([fd69d7f](https://github.com/panva/jose/commit/fd69d7f5093d0b3a231d7d79aa3bca3a8a64464c))\n* removed `nonce` option from `JWT.sign` ([c4267cc](https://github.com/panva/jose/commit/c4267cc655bc2721d846c98f8a40640d1a12e9ad))\n* removed deprecated methods and utilities ([6c35c51](https://github.com/panva/jose/commit/6c35c519c9181f8246b36ad02572adb609d6de1d))\n* removed payload parsing from JWS.verify ([ba5c897](https://github.com/panva/jose/commit/ba5c89791915a2a3cd56b3dab1f3328778152d33))\n\n## [1.28.0](https://github.com/panva/jose/compare/v1.27.3...v1.28.0) (2020-08-10)\n\n\n### Features\n\n* support for validating issuer from a list of values ([#91](https://github.com/panva/jose/issues/91)) ([ce6836a](https://github.com/panva/jose/commit/ce6836af88c9e73c29560233f15ed1760c7dcc13))\n\n\n\n## [1.27.3](https://github.com/panva/jose/compare/v1.27.2...v1.27.3) (2020-08-04)\n\n\n### Fixes\n\n* do not mutate unencoded payload when signing for multiple parties ([1695423](https://github.com/panva/jose/commit/169542363f884e4028db9f80086d631e626eb469)), closes [#89](https://github.com/panva/jose/issues/89)\n* ensure \"b64\" is the same for all recipients edge cases ([d56ec9f](https://github.com/panva/jose/commit/d56ec9f5ddc2612e5ff21fe35d45a56e7153e0e4))\n\n\n\n## [1.27.2](https://github.com/panva/jose/compare/v1.27.1...v1.27.2) (2020-07-01)\n\n\n### Fixes\n\n* handle private EC keys without public component ([#86](https://github.com/panva/jose/issues/86)) ([e8ad389](https://github.com/panva/jose/commit/e8ad38993e29747098f7fd1594dde4ce893ba802)), closes [#85](https://github.com/panva/jose/issues/85)\n\n\n\n## [1.27.1](https://github.com/panva/jose/compare/v1.27.0...v1.27.1) (2020-06-01)\n\n\n### Fixes\n\n* allow any JSON numeric value for timestamp values ([7ba4922](https://github.com/panva/jose/commit/7ba492237aaf788914166c134d50fb046041efa0))\n\n\n\n## [1.27.0](https://github.com/panva/jose/compare/v1.26.1...v1.27.0) (2020-05-05)\n\n\n### Features\n\n* add opt-in objects to verify using embedded JWS Header public keys ([7c1cab1](https://github.com/panva/jose/commit/7c1cab196edc409ec6cc4741bdf7e06c5aaf5dab))\n\n\n\n## [1.26.1](https://github.com/panva/jose/compare/v1.26.0...v1.26.1) (2020-04-27)\n\n\n### Fixes\n\n* **typescript:** types of key generate functions without overloads ([7e60722](https://github.com/panva/jose/commit/7e60722ae7054f8acf833e015c22679d56fbc0ca)), closes [#80](https://github.com/panva/jose/issues/80)\n* \"typ\" content-type validation, case insensitive and handled prefix ([0691586](https://github.com/panva/jose/commit/06915861b32c0ae252dcc84791050bc3716ce102))\n\n\n\n## [1.26.0](https://github.com/panva/jose/compare/v1.25.2...v1.26.0) (2020-04-16)\n\n\n### Features\n\n* update JWT Profile for OAuth 2.0 Access Tokens to latest draft ([8c0a8a9](https://github.com/panva/jose/commit/8c0a8a950e4503cb7a756589e307286fe1116b05))\n\n\n### BREAKING CHANGES\n\n* `at+JWT` JWT draft profile - in the draft's Section 2.2\nthe claims `iat` and `jti` are now REQUIRED (was RECOMMENDED).\n\n\n\n## [1.25.2](https://github.com/panva/jose/compare/v1.25.1...v1.25.2) (2020-04-15)\n\n\n### Fixes\n\n* **build:** don't publish junk files ([6e98c1a](https://github.com/panva/jose/commit/6e98c1a5f994224b9412fc47c4065b468c89fe2c))\n\n\n\n## [1.25.1](https://github.com/panva/jose/compare/v1.25.0...v1.25.1) (2020-04-15)\n\n\n### Fixes\n\n* use native openssl AES Key Wrap 🤦 ([dcf8d75](https://github.com/panva/jose/commit/dcf8d75a8aca4f05fe04df64fdd2ba50bbc75bc9))\n\n\n\n## [1.25.0](https://github.com/panva/jose/compare/v1.24.1...v1.25.0) (2020-03-11)\n\n\n### Features\n\n* update JWT Profile for OAuth 2.0 Access Tokens to latest draft ([bc77a15](https://github.com/panva/jose/commit/bc77a15fab10f8a29561ef667a923b2f074fa9b3))\n\n\n\n## [1.24.1](https://github.com/panva/jose/compare/v1.24.0...v1.24.1) (2020-03-05)\n\n\n### Fixes\n\n* allow importing simpler passphrases as `oct` keys ([f86bda3](https://github.com/panva/jose/commit/f86bda3bb709f29e4264fb8de45242f518128744))\n\n\n\n## [1.24.0](https://github.com/panva/jose/compare/v1.23.0...v1.24.0) (2020-02-25)\n\n\n### Features\n\n* add JWT.verify \"typ\" option for checking JWT Type Header parameter ([fc08426](https://github.com/panva/jose/commit/fc08426466233709b442ba21232768ddeeb94e56))\n\n\n\n## [1.23.0](https://github.com/panva/jose/compare/v1.22.2...v1.23.0) (2020-02-18)\n\n\n### Fixes\n\n* **typescript:** add optional JWK.Key props and make them readonly ([b92079c](https://github.com/panva/jose/commit/b92079cb64216b8ea91082adc07ac03972dbbb0e)), closes [#67](https://github.com/panva/jose/issues/67)\n\n\n### Features\n\n* add ECDH-ES with X25519 and X448 OKP keys ([38369ea](https://github.com/panva/jose/commit/38369ea3d72812abe7ecebd6dc7da164b0a2e29d))\n* add RSA-OAEP-384 and RSA-OAEP-512 JWE Key Management Algorithms ([7477f08](https://github.com/panva/jose/commit/7477f0831b38765a9a916b35b1d40aaf11f0e6b8))\n\n\n\n## [1.22.2](https://github.com/panva/jose/compare/v1.22.1...v1.22.2) (2020-02-06)\n\n\n### Performance Improvements\n\n* various codepaths refactored ([3e3d7dd](https://github.com/panva/jose/commit/3e3d7dd38168159e188e54c48a9f83e3a02a8fe1))\n\n\n\n## [1.22.1](https://github.com/panva/jose/compare/v1.22.0...v1.22.1) (2020-02-03)\n\n\n### Fixes\n\n* actually remove the base64url proper encoding check ([eae01b5](https://github.com/panva/jose/commit/eae01b57ab9f33e8c621ffcd2a77d513a51d22b2))\n\n\n\n## [1.22.0](https://github.com/panva/jose/compare/v1.21.1...v1.22.0) (2020-01-29)\n\n\n### Features\n\n* keystore filtering by JWK Key thumbprint ([a9f6f71](https://github.com/panva/jose/commit/a9f6f7135005d6231d6f42d95c02414139a89d17))\n\n\n### Performance Improvements\n\n* base64url decode, JWT.verify, JWK.Key instance re-use ([470b4c7](https://github.com/panva/jose/commit/470b4c73154e1fcf8b92726d521940e5e11c9d94))\n\n\n\n## [1.21.1](https://github.com/panva/jose/compare/v1.21.0...v1.21.1) (2020-01-25)\n\n\n### Fixes\n\n* contactKDF iteration count fixed for key sizes larger than 256 bits ([70ff222](https://github.com/panva/jose/commit/70ff22227ad303e57228dc8351688531499a833a))\n\n\n\n## [1.21.0](https://github.com/panva/jose/compare/v1.20.0...v1.21.0) (2020-01-23)\n\n\n### Fixes\n\n* **typescript:** don't expose non existant classes, fix decode key ([0f8bf88](https://github.com/panva/jose/commit/0f8bf886da1b5d02cd0d968d0ec02a58673df258))\n\n\n### Features\n\n* add opt-in support for Unsecured JWS algorithm \"none\" ([3a6d17f](https://github.com/panva/jose/commit/3a6d17fdd18d8bbd074c07c2dd08f0406c16a8f1))\n\n\n\n## [1.20.0](https://github.com/panva/jose/compare/v1.19.0...v1.20.0) (2020-01-16)\n\n\n### Features\n\n* add JWTExpired error and JWTClaimInvalid claim and reason props ([a0c0c7a](https://github.com/panva/jose/commit/a0c0c7ad70f42d9b23b3e71de43599a8ac6fe1ff)), closes [#62](https://github.com/panva/jose/issues/62)\n\n\n\n## [1.19.0](https://github.com/panva/jose/compare/v1.18.2...v1.19.0) (2020-01-13)\n\n\n### Features\n\n* exposed shorthands for JWT verification profiles ([b1864e3](https://github.com/panva/jose/commit/b1864e319d1a7a42eadfa0c4b0145952e7814726))\n\n\n\n## [1.18.2](https://github.com/panva/jose/compare/v1.18.1...v1.18.2) (2020-01-08)\n\n\n### Fixes\n\n* ensure asn1.js version to remove Buffer deprecation notice ([13b1106](https://github.com/panva/jose/commit/13b1106048fdeae00b09d54f05245dded85b14a7))\n* expose JOSENotSupported key import errors on unsupported runtimes ([bc81e5d](https://github.com/panva/jose/commit/bc81e5dec2987f6ce6dc3fa5daa23dfe620c0a34))\n* typo in JOSENotSupported error when x509 certs are not supported ([bb58c9c](https://github.com/panva/jose/commit/bb58c9ce52e807ca4cfad6bcbf1ab96b91778b1f))\n\n\n\n## [1.18.1](https://github.com/panva/jose/compare/v1.18.0...v1.18.1) (2020-01-01)\n\n\n### Fixes\n\n* force iat past check when maxTokenAge option is used + JWT refactor ([828ad5a](https://github.com/panva/jose/commit/828ad5a33dc0cc0049923b69f43f97463295456e))\n\n\n\n## [1.18.0](https://github.com/panva/jose/compare/v1.17.2...v1.18.0) (2019-12-31)\n\n\n### Features\n\n* add JWT validation profiles for Access Tokens and Logout Tokens ([7bb5c95](https://github.com/panva/jose/commit/7bb5c953a9c6d9bd915e8ebc0608bc0649427745))\n\n\n\n## [1.17.2](https://github.com/panva/jose/compare/v1.17.1...v1.17.2) (2019-12-17)\n\n\n### Fixes\n\n* skip validating iat is in the past when exp is present ([0ed5025](https://github.com/panva/jose/commit/0ed5025de30a754de95ae2587ce0f4573909b006))\n\n\n\n## [1.17.1](https://github.com/panva/jose/compare/v1.17.0...v1.17.1) (2019-12-10)\n\n\n### Fixes\n\n* properly fail to import unsupported openssh keys ([bee5744](https://github.com/panva/jose/commit/bee574457f29597ccab09d51ac61b85dd7a7146a))\n\n\n\n## [1.17.0](https://github.com/panva/jose/compare/v1.16.2...v1.17.0) (2019-12-10)\n\n\n### Features\n\n* importing a certificate populates x5c and x5t thumbprints ([25a7a71](https://github.com/panva/jose/commit/25a7a71915c4f7514536cec9e7e162d0ad3b670c)), closes [#59](https://github.com/panva/jose/issues/59)\n\n\n\n## [1.16.2](https://github.com/panva/jose/compare/v1.16.1...v1.16.2) (2019-12-05)\n\n\n### Fixes\n\n* handle Unencoded Payload (b64:false) with arbitrary buffer payloads ([daabedc](https://github.com/panva/jose/commit/daabedc776617f4fde427b3a5e79d8c176293132)), closes [#57](https://github.com/panva/jose/issues/57)\n\n\n\n## [1.16.1](https://github.com/panva/jose/compare/v1.16.0...v1.16.1) (2019-12-05)\n\n\n### Fixes\n\n* allow PBES2 for the correct JWK `use` values ([f0d7194](https://github.com/panva/jose/commit/f0d719416ec9ca041ea88b8a983b5d899a6aa107))\n\n\n\n## [1.16.0](https://github.com/panva/jose/compare/v1.15.1...v1.16.0) (2019-12-04)\n\n\n### Features\n\n* two official jose plugins/extensions for those living on the edge ([5b27c97](https://github.com/panva/jose/commit/5b27c97ac8836ffa9f3880e009c8db5afbfbaa2c)), closes [#56](https://github.com/panva/jose/issues/56)\n\n\n\n## [1.15.1](https://github.com/panva/jose/compare/v1.15.0...v1.15.1) (2019-11-30)\n\n\n### Fixes\n\n* **typescript:** export Key Input types ([0277fcd](https://github.com/panva/jose/commit/0277fcd1896af497e79190212b0719f7e62366c1))\n\n\n\n## [1.15.0](https://github.com/panva/jose/compare/v1.14.0...v1.15.0) (2019-11-27)\n\n\n### Fixes\n\n* default JWT.sign `kid` option value is false for HMAC signatures ([ce77388](https://github.com/panva/jose/commit/ce7738825403f8cdb8f99cb51c096baf0dfa3af7))\n\n\n### Features\n\n* allow JWK.asKey inputs for sign/verify/encrypt/decrypt operations ([5e1009a](https://github.com/panva/jose/commit/5e1009a63e4bc829009cc46d6295c00f8431024c))\n\n\n\n## [1.14.0](https://github.com/panva/jose/compare/v1.13.0...v1.14.0) (2019-11-26)\n\n\n### Features\n\n* allow JWKS.KeyStore .all and .get to filter for key curves ([ea60338](https://github.com/panva/jose/commit/ea60338ca6f58f2626992a38da76812477ce4540))\n\n\n\n## [1.13.0](https://github.com/panva/jose/compare/v1.12.1...v1.13.0) (2019-11-23)\n\n\n### Features\n\n* return the CEK from JWE.decrypt operation with { complete: true } ([c3eb845](https://github.com/panva/jose/commit/c3eb8450b98b2f5ecc127d69afe85a7ae2cc5aaa))\n\n\n\n## [1.12.1](https://github.com/panva/jose/compare/v1.12.0...v1.12.1) (2019-11-14)\n\n\n\n## [1.12.0](https://github.com/panva/jose/compare/v1.11.0...v1.12.0) (2019-11-05)\n\n\n### Features\n\n* add JWS.verify encoding and parsing options ([6bb66d4](https://github.com/panva/jose/commit/6bb66d4f0b4c96f2da8ac5f14fda6bc4f53f2994))\n\n\n\n## [1.11.0](https://github.com/panva/jose/compare/v1.10.2...v1.11.0) (2019-11-03)\n\n\n### Features\n\n* expose crypto.KeyObject instances in supported runtimes ([8ea9683](https://github.com/panva/jose/commit/8ea968312e97ed0f992fab909a20e7993159ec45))\n\n\n\n## [1.10.2](https://github.com/panva/jose/compare/v1.10.1...v1.10.2) (2019-10-29)\n\n\n### Fixes\n\n* only use secp256k1 keys for signing/verification ([9588223](https://github.com/panva/jose/commit/95882232d6d409a321b6a8c168f5b78ebbdabf95))\n\n\n\n## [1.10.1](https://github.com/panva/jose/compare/v1.10.0...v1.10.1) (2019-10-04)\n\n\n### Fixes\n\n* throw proper error when runtime doesn't support OKP ([0a16efb](https://github.com/panva/jose/commit/0a16efb)), closes [#48](https://github.com/panva/jose/issues/48)\n\n\n\n## [1.10.0](https://github.com/panva/jose/compare/v1.9.2...v1.10.0) (2019-10-01)\n\n\n### Features\n\n* rename package ([26f4cf2](https://github.com/panva/jose/commit/26f4cf2))\n\n\n\n## [1.9.2](https://github.com/panva/jose/compare/v1.9.1...v1.9.2) (2019-09-16)\n\n\n### Fixes\n\n* keystore.toJWKS(true) does not throw on public keys ([81abdfa](https://github.com/panva/jose/commit/81abdfa)), closes [#42](https://github.com/panva/jose/issues/42)\n\n\n\n## [1.9.1](https://github.com/panva/jose/compare/v1.9.0...v1.9.1) (2019-09-10)\n\n\n\n## [1.9.0](https://github.com/panva/jose/compare/v1.8.0...v1.9.0) (2019-08-24)\n\n\n### Features\n\n* allow JWKS.asKeyStore to swallow errors ([78398d3](https://github.com/panva/jose/commit/78398d3))\n\n\n\n## [1.8.0](https://github.com/panva/jose/compare/v1.7.0...v1.8.0) (2019-08-22)\n\n\n### Features\n\n* added Node.js lts/dubnium support for runtime supported features ([67a8601](https://github.com/panva/jose/commit/67a8601))\n\n\n\n## [1.7.0](https://github.com/panva/jose/compare/v1.6.1...v1.7.0) (2019-08-20)\n\n\n### Features\n\n* add RSA-OAEP-256 support (when a node version supports it) ([28d7cf8](https://github.com/panva/jose/commit/28d7cf8)), closes [#29](https://github.com/panva/jose/issues/29)\n\n\n\n## [1.6.1](https://github.com/panva/jose/compare/v1.6.0...v1.6.1) (2019-07-29)\n\n\n### Fixes\n\n* properly pad calculated RSA primes ([dd121ce](https://github.com/panva/jose/commit/dd121ce))\n\n\n\n## [1.6.0](https://github.com/panva/jose/compare/v1.5.2...v1.6.0) (2019-07-27)\n\n\n### Fixes\n\n* use the correct ECPrivateKey version when importing EC JWK ([24acd20](https://github.com/panva/jose/commit/24acd20))\n\n\n### Features\n\n* electron v6.x support ([e7ad82c](https://github.com/panva/jose/commit/e7ad82c))\n\n\n\n## [1.5.2](https://github.com/panva/jose/compare/v1.5.1...v1.5.2) (2019-07-27)\n\n\n### Fixes\n\n* importing x5c in electron requires the input split ([181fd09](https://github.com/panva/jose/commit/181fd09))\n\n\n\n## [1.5.1](https://github.com/panva/jose/compare/v1.5.0...v1.5.1) (2019-07-27)\n\n\n### Fixes\n\n* correctly pad integers when importing RSA JWK ([1dc7f35](https://github.com/panva/jose/commit/1dc7f35))\n\n\n\n## [1.5.0](https://github.com/panva/jose/compare/v1.4.1...v1.5.0) (2019-07-23)\n\n\n### Features\n\n* validate JWTs according to a JWT profile - ID Token ([6c98b61](https://github.com/panva/jose/commit/6c98b61))\n\n\n\n## [1.4.1](https://github.com/panva/jose/compare/v1.4.0...v1.4.1) (2019-07-14)\n\n\n### Fixes\n\n* honour the JWT.sign `jti` option ([36c9ce2](https://github.com/panva/jose/commit/36c9ce2)), closes [#33](https://github.com/panva/jose/issues/33)\n\n\n\n## [1.4.0](https://github.com/panva/jose/compare/v1.3.0...v1.4.0) (2019-07-08)\n\n\n### Features\n\n* add secp256k1 EC Key curve and ES256K ([211d7af](https://github.com/panva/jose/commit/211d7af))\n\n\n\n## [1.3.0](https://github.com/panva/jose/compare/v1.0.2...c51dc28) (2019-06-21)\n\n\n### Features\n\n* compute private RSA key p, q, dp, dq, qi when omitted ([6e3d6fd](https://github.com/panva/jose/commit/6e3d6fd)), closes [#26](https://github.com/panva/jose/issues/26)\n* add support for JWK x5c, x5t and x5t#S256 ([9d46c48](https://github.com/panva/jose/commit/9d46c48))\n* instances of JWKS.KeyStore are now iterable (e.g. for ... of) ([2eae293](https://github.com/panva/jose/commit/2eae293))\n\n### Fixes\n\n* limit calculation of missing RSA private components ([5b53cb0](https://github.com/panva/jose/commit/5b53cb0))\n* reject rsa keys without all factors and exponents with a specific message ([b0ff436](https://github.com/panva/jose/commit/b0ff436))\n\n### Deprecations\n\n- this deprecates the use of `JWK.importKey` in favor of\n`JWK.asKey`\n- this deprecates the use of `JWKS.KeyStore.fromJWKS` in favor of\n`JWKS.asKeyStore`\n\nBoth `JWK.importKey` and `JWKS.KeyStore.fromJWKS` could have resulted\nin the process getting blocked when large bitsize RSA private keys\nwere missing their components and could also result in an endless\ncalculation loop when the private key's private exponent was outright\ninvalid or tampered with.\n\nThe new methods still allow to import private RSA keys with these\noptimization key parameters missing but it is disabled by default and one\nshould choose to enable it when working with keys from trusted sources\n\nIt is recommended not to use `jose` versions with this feature in\nits original on-by-default form - v1.1.0 and v1.2.0\n\n\n\n## [1.0.2](https://github.com/panva/jose/compare/v1.0.1...v1.0.2) (2019-05-13)\n\n\n### Fixes\n\n* add missing keystore.toJWKS() .d.ts definition ([c7a8606](https://github.com/panva/jose/commit/c7a8606)), closes [#25](https://github.com/panva/jose/issues/25)\n\n\n\n## [1.0.1](https://github.com/panva/jose/compare/v1.0.0...v1.0.1) (2019-04-27)\n\n\n### Fixes\n\n* oct key ts \"k\" type fix ([0750d2c](https://github.com/panva/jose/commit/0750d2c))\n\n\n\n## [1.0.0](https://github.com/panva/jose/compare/v0.12.0...v1.0.0) (2019-04-23)\n\n\n### Fixes\n\n* fail to import invalid PEM formatted strings and buffers ([857dc2b](https://github.com/panva/jose/commit/857dc2b))\n\n\n### Features\n\n* add JWK key_ops support, fix .algorithms() op returns ([23b874c](https://github.com/panva/jose/commit/23b874c))\n* add key.toPEM() export function with optional encryption ([1159b0d](https://github.com/panva/jose/commit/1159b0d))\n* add OKP Key and EdDSA sign/verify support ([2dbd3ed](https://github.com/panva/jose/commit/2dbd3ed)), closes [#12](https://github.com/panva/jose/issues/12)\n\n\n### BREAKING CHANGES\n\n* key.algorithms(op) un+wrapKey was split into correct\nwrapKey/unwrapKey/deriveKey returns\n* keystore.all and keystore.get `operation` option was\nremoved, `key_ops: string[]` supersedes it\n* Node.js minimal version is now v12.0.0 due to its\nadded EdDSA support (crypto.sign, crypto.verify and eddsa key objects)\n\n\n\n## [0.12.0](https://github.com/panva/jose/compare/v0.11.5...v0.12.0) (2019-04-07)\n\n\n### Reverts\n\n* add EC P-256K JWK and ES256K sign/verify support ([e21fea1](https://github.com/panva/jose/commit/e21fea1))\n\n\n### BREAKING CHANGES\n\n* removing ES256K alg and EC P-256K crv support until the\nIETF WG decides on what the final names will be.\n\n\n\n## [0.11.5](https://github.com/panva/jose/compare/v0.11.4...v0.11.5) (2019-04-04)\n\n\n### Features\n\n* add key.secret<boolean> and key.type<string> for completeness ([2dd7053](https://github.com/panva/jose/commit/2dd7053))\n* add key.thumbprint always returning the JWK Thumbprint (RFC7638) ([65db7e0](https://github.com/panva/jose/commit/65db7e0))\n\n\n\n## [0.11.4](https://github.com/panva/jose/compare/v0.11.3...v0.11.4) (2019-03-28)\n\n\n### Fixes\n\n* properly restrict EC curves in generate(Sync) ([764b863](https://github.com/panva/jose/commit/764b863))\n* remove unintended exposure of private material via enumerables ([946d9df](https://github.com/panva/jose/commit/946d9df))\n\n\n\n## [0.11.3](https://github.com/panva/jose/compare/v0.11.2...v0.11.3) (2019-03-27)\n\n\n### Fixes\n\n* throw on unsupported EC curves ([cfa4222](https://github.com/panva/jose/commit/cfa4222))\n\n\n### Features\n\n* add EC P-256K JWK and ES256K sign/verify support ([2e33e1c](https://github.com/panva/jose/commit/2e33e1c))\n\n\n\n## [0.11.2](https://github.com/panva/jose/compare/v0.11.1...v0.11.2) (2019-03-19)\n\n\n### Fixes\n\n* internal symbol method is now really a symbol ([925d47c](https://github.com/panva/jose/commit/925d47c))\n* key.toJWK() fixed on windows ([57f1692](https://github.com/panva/jose/commit/57f1692)), closes [#17](https://github.com/panva/jose/issues/17)\n\n\n## [0.11.1](https://github.com/panva/jose/compare/v0.11.0...v0.11.1) (2019-03-17)\n\n\n### Fixes\n\n* restrict RS key algorithms by the key's bit size ([9af295b](https://github.com/panva/jose/commit/9af295b))\n\n\n## [0.11.0](https://github.com/panva/jose/compare/v0.10.0...v0.11.0) (2019-03-16)\n\n\n### Fixes\n\n* all JWA defined RSA operations require key of 2048 or more ([cc70c5d](https://github.com/panva/jose/commit/cc70c5d))\n* use correct salt length for RSASSA-PSS ([e936d54](https://github.com/panva/jose/commit/e936d54))\n\n\n### BREAKING CHANGES\n\n* all [JWA](https://www.rfc-editor.org/rfc/rfc7518) defined\nRSA based operations require key size of 2048 bits or more.\n\n\n\n## [0.10.0](https://github.com/panva/jose/compare/v0.9.2...v0.10.0) (2019-03-12)\n\n\n### Fixes\n\n* do not list \"dir\" under wrap/unwrapKey operations ([17b37d3](https://github.com/panva/jose/commit/17b37d3))\n\n\n### Features\n\n* keystore .all and .get operation option ([d349ba9](https://github.com/panva/jose/commit/d349ba9))\n\n\n### BREAKING CHANGES\n\n* \"dir\" is no longer returned as wrap/unwrapKey key\noperation\n\n\n\n## [0.9.2](https://github.com/panva/jose/compare/v0.9.1...v0.9.2) (2019-03-05)\n\n\n### Fixes\n\n* \"dir\" is only available on keys with correct lengths ([6854860](https://github.com/panva/jose/commit/6854860))\n* do not 'in' operator when importing keys as string ([be3f4e4](https://github.com/panva/jose/commit/be3f4e4))\n\n\n\n## [0.9.1](https://github.com/panva/jose/compare/v0.9.0...v0.9.1) (2019-03-02)\n\n\n### Fixes\n\n* only import RSA, EC and oct successfully ([e5e02fc](https://github.com/panva/jose/commit/e5e02fc))\n\n\n# 0.9.0 (2019-03-02)\n\nInitial release\n\n### Implemented Features\n\n- JSON Web Signature (JWS) - [RFC7515][spec-jws]\n- JSON Web Encryption (JWE) - [RFC7516][spec-jwe]\n- JSON Web Key (JWK) - [RFC7517][spec-jwk]\n- JSON Web Algorithms (JWA) - [RFC7518][spec-jwa]\n- JSON Web Token (JWT) - [RFC7519][spec-jwt]\n- JSON Web Key (JWK) Thumbprint - [RFC7638][spec-thumbprint]\n- JWS Unencoded Payload Option - [RFC7797][spec-b64]\n\n| JWK Key Types | Supported ||\n| -- | -- | -- |\n| RSA | ✓ | RSA |\n| Elliptic Curve | ✓ | EC |\n| Octet sequence | ✓ | oct |\n\n| Serialization | JWS Sign | JWS Verify | JWE Encrypt | JWE Decrypt |\n| -- | -- | -- | -- | -- |\n| Compact | ✓ | ✓ | ✓ | ✓ |\n| General JSON | ✓ | ✓ | ✓ | ✓ |\n| Flattened JSON  | ✓ | ✓ | ✓ | ✓ |\n\n| JWS Algorithms | Supported ||\n| -- | -- | -- |\n| RSASSA-PKCS1-v1_5 | ✓ | RS256, RS384, RS512 |\n| RSASSA-PSS | ✓ | PS256, PS384, PS512 |\n| ECDSA | ✓ | ES256, ES384, ES512 |\n| HMAC with SHA-2 | ✓ | HS256, HS384, HS512 |\n\n| JWE Key Management Algorithms | Supported ||\n| -- | -- | -- |\n| AES | ✓ | A128KW, A192KW, A256KW |\n| AES GCM | ✓ | A128GCMKW, A192GCMKW, A256GCMKW |\n| Direct Key Agreement | ✓ | dir |\n| RSAES OAEP | ✓<sup>*</sup> | RSA-OAEP <sub>(<sup>*</sup>RSA-OAEP-256 is not supported due to its lack of support in Node.js)</sub> |\n| RSAES-PKCS1-v1_5 | ✓ | RSA1_5 |\n| PBES2 | ✓ | PBES2-HS256+A128KW, PBES2-HS384+A192KW, PBES2-HS512+A256KW |\n| ECDH-ES | ✓ | ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW |\n\n| JWE Content Encryption Algorithms | Supported ||\n| -- | -- | -- |\n| AES GCM | ✓ | A128GCM, A192GCM, A256GCM |\n| AES_CBC_HMAC_SHA2 | ✓ |  A128CBC-HS256, A192CBC-HS384, A256CBC-HS512 |\n\n[spec-b64]: https://www.rfc-editor.org/rfc/rfc7797\n[spec-jwa]: https://www.rfc-editor.org/rfc/rfc7518\n[spec-jwe]: https://www.rfc-editor.org/rfc/rfc7516\n[spec-jwk]: https://www.rfc-editor.org/rfc/rfc7517\n[spec-jws]: https://www.rfc-editor.org/rfc/rfc7515\n[spec-jwt]: https://www.rfc-editor.org/rfc/rfc7519\n[spec-thumbprint]: https://www.rfc-editor.org/rfc/rfc7638\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, caste, color, religion, or sexual identity\nand orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n* Demonstrating empathy and kindness toward other people\n* Being respectful of differing opinions, viewpoints, and experiences\n* Giving and gracefully accepting constructive feedback\n* Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n* Focusing on what is best not just for us as individuals, but for the\n  overall community\n\nExamples of unacceptable behavior include:\n\n* The use of sexualized language or imagery, and sexual attention or\n  advances of any kind\n* Trolling, insulting or derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or email\n  address, without their explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official e-mail address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\npanva.ip@gmail.com.\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series\nof actions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or\npermanent ban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior,  harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within\nthe community.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.0, available at\n[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].\n\nCommunity Impact Guidelines were inspired by \n[Mozilla's code of conduct enforcement ladder][Mozilla CoC].\n\nFor answers to common questions about this code of conduct, see the FAQ at\n[https://www.contributor-covenant.org/faq][FAQ]. Translations are available \nat [https://www.contributor-covenant.org/translations][translations].\n\n[homepage]: https://www.contributor-covenant.org\n[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html\n[Mozilla CoC]: https://github.com/mozilla/diversity\n[FAQ]: https://www.contributor-covenant.org/faq\n[translations]: https://www.contributor-covenant.org/translations\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to jose\n\nPlease note we have a [code of conduct][coc], please follow it in all your interactions with the\nproject.\n\nWhen contributing to this project, please first discuss the change you wish to make via a discussion,\nemail, or any other appropriate method with the owners of this project before proposing a change \nvia a Pull Request. The project promotes and follows current best practices in regards to the \nspecifications it implements. A contribution that tries to implement something non-standard will most \nlikely be dismissed.\n\n## Rules of the discussions\n\nRemember to be very clear and transparent when discussing any issue in the discussions boards. We\nask that you keep the language to English and keep on track with the issue at hand. Lastly, please\nbe respectful of our fellow contributors and keep an exemplary level of professionalism at all\ntimes.\n\n[coc]: https://github.com/panva/jose/blob/main/CODE_OF_CONDUCT.md\n"
  },
  {
    "path": "LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2018 Filip Skokan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# jose\n\n`jose` is a JavaScript module for JSON Object Signing and Encryption, providing support for JSON Web Tokens (JWT), JSON Web Signature (JWS), JSON Web Encryption (JWE), JSON Web Key (JWK), JSON Web Key Set (JWKS), and more. The module is designed to work across various Web-interoperable runtimes including Node.js, browsers, Cloudflare Workers, Deno, Bun, and others.\n\n## Sponsor\n\n<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/panva/jose/HEAD/sponsor/Auth0byOkta_dark.png\">\n  <source media=\"(prefers-color-scheme: light)\" srcset=\"https://raw.githubusercontent.com/panva/jose/HEAD/sponsor/Auth0byOkta_light.png\">\n  <img height=\"65\" align=\"left\" alt=\"Auth0 by Okta\" src=\"https://raw.githubusercontent.com/panva/jose/HEAD/sponsor/Auth0byOkta_light.png\">\n</picture>\n\nIf you want to quickly add JWT authentication to JavaScript apps, feel free to check out Auth0's JavaScript SDK and free plan. [Create an Auth0 account; it's free!][sponsor-auth0]<br><br>\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n## Dependencies: 0\n\n`jose` has no dependencies and it exports tree-shakeable ESM[^cjs].\n\n## Documentation\n\n`jose` is distributed via [npmjs.com](https://www.npmjs.com/package/jose), [jsr.io](https://jsr.io/@panva/jose), [jsdelivr.com](https://www.jsdelivr.com/package/npm/jose), and [github.com](https://github.com/panva/jose).\n\n**`example`** ESM import[^cjs]\n\n```js\nimport * as jose from 'jose'\n```\n\n### JSON Web Tokens (JWT)\n\nThe `jose` module supports JSON Web Tokens (JWT) and provides functionality for signing and verifying tokens, as well as their JWT Claims Set validation.\n\n- [JWT Claims Set Validation & Signature Verification](docs/jwt/verify/functions/jwtVerify.md) using the `jwtVerify` function\n  - [Using a remote JSON Web Key Set (JWKS)](docs/jwks/remote/functions/createRemoteJWKSet.md)\n  - [Using a local JSON Web Key Set (JWKS)](docs/jwks/local/functions/createLocalJWKSet.md)\n- [Signing](docs/jwt/sign/classes/SignJWT.md) using the `SignJWT` class\n- Utility functions\n  - [Decoding Token's Protected Header](docs/util/decode_protected_header/functions/decodeProtectedHeader.md)\n  - [Decoding JWT Claims Set](docs/util/decode_jwt/functions/decodeJwt.md) prior to its validation\n\n### Encrypted JSON Web Tokens\n\nThe `jose` module supports encrypted JSON Web Tokens and provides functionality for encrypting and decrypting tokens, as well as their JWT Claims Set validation.\n\n- [Decryption & JWT Claims Set Validation](docs/jwt/decrypt/functions/jwtDecrypt.md) using the `jwtDecrypt` function\n- [Encryption](docs/jwt/encrypt/classes/EncryptJWT.md) using the `EncryptJWT` class\n- Utility functions\n  - [Decoding Token's Protected Header](docs/util/decode_protected_header/functions/decodeProtectedHeader.md)\n\n### Key Utilities\n\nThe `jose` module supports importing, exporting, and generating keys and secrets in various formats, including PEM formats like SPKI, X.509 certificate, and PKCS #8, as well as JSON Web Key (JWK).\n\n- Key Import Functions\n  - [JWK Import](docs/key/import/functions/importJWK.md)\n  - [Public Key Import (SPKI)](docs/key/import/functions/importSPKI.md)\n  - [Public Key Import (X.509 Certificate)](docs/key/import/functions/importX509.md)\n  - [Private Key Import (PKCS #8)](docs/key/import/functions/importPKCS8.md)\n- Key and Secret Generation Functions\n  - [Asymmetric Key Pair Generation](docs/key/generate_key_pair/functions/generateKeyPair.md)\n  - [Symmetric Secret Generation](docs/key/generate_secret/functions/generateSecret.md)\n- Key Export Functions\n  - [JWK Export](docs/key/export/functions/exportJWK.md)\n  - [Private Key Export](docs/key/export/functions/exportPKCS8.md)\n  - [Public Key Export](docs/key/export/functions/exportSPKI.md)\n\n### JSON Web Signature (JWS)\n\nThe `jose` module supports signing and verification of JWS messages with arbitrary payloads in Compact, Flattened JSON, and General JSON serialization syntaxes.\n\n- Signing - [Compact](docs/jws/compact/sign/classes/CompactSign.md), [Flattened JSON](docs/jws/flattened/sign/classes/FlattenedSign.md), [General JSON](docs/jws/general/sign/classes/GeneralSign.md)\n- Verification - [Compact](docs/jws/compact/verify/functions/compactVerify.md), [Flattened JSON](docs/jws/flattened/verify/functions/flattenedVerify.md), [General JSON](docs/jws/general/verify/functions/generalVerify.md)\n  - [Using a remote JSON Web Key Set (JWKS)](docs/jwks/remote/functions/createRemoteJWKSet.md)\n  - [Using a local JSON Web Key Set (JWKS)](docs/jwks/local/functions/createLocalJWKSet.md)\n- Utility functions\n  - [Decoding Token's Protected Header](docs/util/decode_protected_header/functions/decodeProtectedHeader.md)\n\n### JSON Web Encryption (JWE)\n\nThe `jose` module supports encryption and decryption of JWE messages with arbitrary plaintext in Compact, Flattened JSON, and General JSON serialization syntaxes.\n\n- Encryption - [Compact](docs/jwe/compact/encrypt/classes/CompactEncrypt.md), [Flattened JSON](docs/jwe/flattened/encrypt/classes/FlattenedEncrypt.md), [General JSON](docs/jwe/general/encrypt/classes/GeneralEncrypt.md)\n- Decryption - [Compact](docs/jwe/compact/decrypt/functions/compactDecrypt.md), [Flattened JSON](docs/jwe/flattened/decrypt/functions/flattenedDecrypt.md), [General JSON](docs/jwe/general/decrypt/functions/generalDecrypt.md)\n- Utility functions\n  - [Decoding Token's Protected Header](docs/util/decode_protected_header/functions/decodeProtectedHeader.md)\n\n### Other\n\nThe following are additional features and utilities provided by the `jose` module:\n\n- [Calculating JWK Thumbprint](docs/jwk/thumbprint/functions/calculateJwkThumbprint.md)\n- [Calculating JWK Thumbprint URI](docs/jwk/thumbprint/functions/calculateJwkThumbprintUri.md)\n- [Verification using a JWK Embedded in a JWS Header](docs/jwk/embedded/functions/EmbeddedJWK.md)\n- [Unsecured JWT](docs/jwt/unsecured/classes/UnsecuredJWT.md)\n- [JOSE Errors](docs/util/errors/README.md)\n\n## Supported Runtimes\n\nThe `jose` module is compatible with JavaScript runtimes that support the utilized Web API globals and standard built-in objects or are Node.js.\n\nThe following runtimes are supported _(this is not an exhaustive list)_:\n\n- [Bun](https://github.com/panva/jose/issues/471)\n- [Browsers](https://github.com/panva/jose/issues/263)\n- [Cloudflare Workers](https://github.com/panva/jose/issues/265)\n- [Deno](https://github.com/panva/jose/issues/266)\n- [Electron](https://github.com/panva/jose/issues/264)\n- [Node.js](https://github.com/panva/jose/issues/262)\n\nPlease note that certain algorithms may not be available depending on the runtime used. You can find a list of available algorithms for each runtime in the specific issue links provided above.\n\n## Supported Versions\n\n| Version                                         | Security Fixes 🔑 | Other Bug Fixes 🐞 | New Features ⭐ | Runtime and Module type         |\n| ----------------------------------------------- | ----------------- | ------------------ | --------------- | ------------------------------- |\n| [v6.x](https://github.com/panva/jose/tree/v6.x) | [Security Policy] | ✅                 | ✅              | Universal[^universal] ESM[^cjs] |\n| [v5.x](https://github.com/panva/jose/tree/v5.x) | [Security Policy] | ❌                 | ❌              | Universal[^universal] CJS + ESM |\n| [v4.x](https://github.com/panva/jose/tree/v4.x) | [Security Policy] | ❌                 | ❌              | Universal[^universal] CJS + ESM |\n| [v2.x](https://github.com/panva/jose/tree/v2.x) | [Security Policy] | ❌                 | ❌              | Node.js CJS                     |\n\n## Specifications\n\n<details>\n<summary>Details</summary>\n\n- JSON Web Signature (JWS) - [RFC7515](https://www.rfc-editor.org/rfc/rfc7515)\n- JSON Web Encryption (JWE) - [RFC7516](https://www.rfc-editor.org/rfc/rfc7516)\n- JSON Web Key (JWK) - [RFC7517](https://www.rfc-editor.org/rfc/rfc7517)\n- JSON Web Algorithms (JWA) - [RFC7518](https://www.rfc-editor.org/rfc/rfc7518)\n- JSON Web Token (JWT) - [RFC7519](https://www.rfc-editor.org/rfc/rfc7519)\n- JSON Web Key Thumbprint - [RFC7638](https://www.rfc-editor.org/rfc/rfc7638)\n- JSON Web Key Thumbprint URI - [RFC9278](https://www.rfc-editor.org/rfc/rfc9278)\n- JWS Unencoded Payload Option - [RFC7797](https://www.rfc-editor.org/rfc/rfc7797)\n- CFRG Elliptic Curve ECDH and Signatures - [RFC8037](https://www.rfc-editor.org/rfc/rfc8037)\n- Fully-Specified Algorithms for JOSE - [RFC9864](https://www.rfc-editor.org/rfc/rfc9864.html)\n- ML-DSA for JOSE - [draft-ietf-cose-dilithium-10](https://www.ietf.org/archive/id/draft-ietf-cose-dilithium-10.html)\n\nThe algorithm implementations in `jose` have been tested using test vectors from their respective specifications as well as [RFC7520](https://www.rfc-editor.org/rfc/rfc7520).\n\n</details>\n\n[sponsor-auth0]: https://a0.to/signup/panva\n[WebCryptoAPI]: https://w3c.github.io/webcrypto/\n[Fetch API]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API\n[Security Policy]: https://github.com/panva/jose/security/policy\n\n[^cjs]: CJS style `let jose = require('jose')` is possible in Node.js versions where the `require(esm)` feature is enabled by default (^20.19.0 || ^22.12.0 || >= 23.0.0).\n\n[^universal]: Assumes runtime support of [WebCryptoAPI][] and [Fetch API][]\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\nThe following major versions are currently supported with security updates.\n\n| Version                                         | End-of-life |\n| ----------------------------------------------- | ----------- |\n| [v6.x](https://github.com/panva/jose/tree/v6.x) | TBD         |\n| [v5.x](https://github.com/panva/jose/tree/v5.x) | 2026-04-30  |\n| [v4.x](https://github.com/panva/jose/tree/v4.x) | 2026-04-30  |\n| [v2.x](https://github.com/panva/jose/tree/v2.x) | 2026-04-30  |\n\nEnd-of-life for the current release will be determined prior to the release of its successor.\n\n## Reporting a Vulnerability\n\nVulnerabilities must be reported using the [project's security advisory](https://github.com/panva/jose/security/advisories/new).\n\n**All vulnerability reports MUST be submitted through the channel listed above.** This allows the maintainers to assess the report, collaborate on remediation, and coordinate disclosure in a responsible manner.\n\nCVE identifiers for confirmed vulnerabilities will only be requested by the maintainers through the GitHub Security Advisory process. Vulnerability reports submitted directly to third-party CVE Numbering Authorities (CNAs), such as MITRE, without first being reported and confirmed through this project's documented channel will be considered as not following the coordinated disclosure process. The maintainers reserve the right to request rejection or dispute of any CVE entry that was assigned without prior coordinated disclosure with the project.\n\n## Threat Model\n\nThis section documents the threat model for `jose`, a JavaScript implementation of JSON Object Signing and Encryption standards including [JSON Web Token (JWT) - RFC 7519](https://www.rfc-editor.org/rfc/rfc7519), [JSON Web Signature (JWS) - RFC 7515](https://www.rfc-editor.org/rfc/rfc7515), [JSON Web Encryption (JWE) - RFC 7516](https://www.rfc-editor.org/rfc/rfc7516), [JSON Web Key (JWK) - RFC 7517](https://www.rfc-editor.org/rfc/rfc7517), and [JSON Web Algorithms (JWA) - RFC 7518](https://www.rfc-editor.org/rfc/rfc7518).\n\n### Purpose and Intended Users\n\nThis library is intended for general application developers, cryptography practitioners, and anyone needing JOSE functionality in JavaScript runtimes (Node.js, browsers, Cloudflare Workers, Deno, Bun, and other Web-interoperable environments).\n\n### Trust Assumptions\n\n#### Underlying Cryptographic Primitives\n\nThis library trusts that the Web Cryptography implementations provided by the runtime are correct and secure. The library delegates all cryptographic operations (key generation, signing, verification, encryption, decryption, key derivation, etc.) to the runtime's Web Cryptography implementation and does not attempt to validate or verify the correctness of these underlying primitives.\n\n#### Runtime Environment\n\nThe library assumes it is running in a trusted execution environment. The following are considered outside the scope of this library's threat model:\n\n- **Prototype pollution attacks**: If an attacker can modify JavaScript prototypes, this is considered a vulnerability in the user's application code or the runtime environment, not in this library.\n- **Debugger access**: If an attacker has debugger access to the running process, they can inspect memory, modify variables, and bypass security controls. This is a runtime-level compromise, not a library vulnerability.\n- **Runtime compromise**: Attacks that compromise the JavaScript runtime itself (e.g., malicious runtime modifications, compromised Node.js binaries, malicious browser extensions with elevated privileges) are not considered attacks on this library.\n\n#### Remote JWKS Sources\n\nWhen using remote JSON Web Key Sets (JWKS) via `createRemoteJWKSet`, the library assumes that users configure trusted JWKS sources. The security of key material fetched from remote sources depends on the trustworthiness of those sources and the security of the transport (HTTPS).\n\n#### Key Material\n\nPrivate keys and secret key material provided by users for signing, decryption, or key management operations are considered trusted and fitting the user's own security requirements. The library does not validate that key material originates from a secure source or has been handled securely prior to being provided.\n\n#### Key and Secret Sizes\n\nAs cryptographic requirements on key and secret sizes evolve over time, following these developments is the user's responsibility. The library implements reasonable measures where practical, but in the spirit of interoperability with other implementations, it does not enforce strict key size requirements for all algorithms. For example, the library cannot prevent use of short HMAC secret keys because such restrictions are easily sidestepped and would hinder interoperability.\n\n#### Input Size Limits\n\nThe library does not enforce size limits on any inputs (tokens, keys, payloads, headers, etc.). It is the application's responsibility to enforce input size limits appropriate for its context before passing data to the library. Without such limits, an attacker could supply arbitrarily large inputs that consume excessive memory or processing time.\n\n#### Side-Channel Attacks\n\nThis library delegates all cryptographic operations to the underlying Web Cryptography. Any resistance to side-channel attacks (timing attacks, cache attacks, etc.) is entirely dependent on the underlying cryptographic implementations and is outside the scope of this library.\n\n### Security Guarantees\n\nThis library aims to provide the following security guarantees:\n\n- **Specification compliance**: Correct implementation of the JOSE family of specifications (RFC 7515, RFC 7516, RFC 7517, RFC 7518, RFC 7519, and related RFCs), validated against test vectors from the respective specifications.\n- **JWT Claims Set validation**: Proper validation of JWT claims (`exp`, `nbf`, `iat`, `aud`, `iss`, etc.) as defined by the underlying RFCs.\n- **Input validation**: Validation of inputs to prevent misuse of the API.\n\n### Out of Scope\n\n#### Key Management\n\nThis library does not handle key storage. Users are responsible for securely storing, managing, and distributing cryptographic keys.\n\n#### Memory Clearing\n\nThis library does not guarantee that key material or other sensitive data is cleared from memory after use. As long as the user retains references to key objects, the key material may remain in memory. Secure memory management is the responsibility of the user and the runtime environment.\n\n### Threat Actors and Security Properties\n\nThis library aims to provide the security properties defined by the JOSE specifications. For detailed security considerations, refer to the Security Considerations sections in [RFC 7515 (JWS)](https://www.rfc-editor.org/rfc/rfc7515#section-10), [RFC 7516 (JWE)](https://www.rfc-editor.org/rfc/rfc7516#section-11), [RFC 7517 (JWK)](https://www.rfc-editor.org/rfc/rfc7517#section-9), [RFC 7518 (JWA)](https://www.rfc-editor.org/rfc/rfc7518#section-8), and [RFC 7519 (JWT)](https://www.rfc-editor.org/rfc/rfc7519#section-8).\n\n### What is NOT Considered a Vulnerability\n\nThe following are explicitly **not** considered vulnerabilities in this library:\n\n- **Prototype pollution** ([CWE-1321](https://cwe.mitre.org/data/definitions/1321.html)): Attacks that exploit JavaScript prototype pollution are considered vulnerabilities in user application code or the runtime, not this library.\n- **Object injection** ([CWE-915](https://cwe.mitre.org/data/definitions/915.html)): Similar to prototype pollution, object injection attacks are outside the scope of this library.\n- **Debugger/inspector access** ([CWE-489](https://cwe.mitre.org/data/definitions/489.html)): If an attacker can attach a debugger to the process, they have already compromised the runtime environment.\n- **Memory inspection**: Reading process memory, heap dumps, or core dumps to extract key material is a runtime-level attack.\n- **Side-channel attacks** ([CWE-208](https://cwe.mitre.org/data/definitions/208.html)): Timing attacks, cache attacks, and other side-channel vulnerabilities in the underlying Web Cryptography implementations are not vulnerabilities in this library.\n- **Compromised runtime environment**: Malicious or backdoored JavaScript runtimes, compromised system libraries, or tampered Web Cryptography implementations.\n- **Supply chain attacks on the runtime** ([CWE-1357](https://cwe.mitre.org/data/definitions/1357.html)): Compromised Node.js binaries, malicious browser builds, or similar supply chain attacks on the execution environment.\n- **Denial of service via resource exhaustion** ([CWE-400](https://cwe.mitre.org/data/definitions/400.html)): While the library validates inputs, it does not implement resource limits. Applications should implement their own rate limiting and resource management.\n- **Oversized inputs** ([CWE-400](https://cwe.mitre.org/data/definitions/400.html)): The library does not enforce size limits on JWTs, JWS, JWE, JWK, or JWKS inputs. Enforcing input size limits appropriate for the application's context (e.g., limiting the size of incoming tokens or payloads before passing them to the library) is the responsibility of the application.\n- **Untrusted JWKS sources**: Security issues arising from fetching keys from untrusted or compromised JWKS endpoints are the user's responsibility.\n"
  },
  {
    "path": "ava.config.mjs",
    "content": "const files = ['test/**/*.test.ts']\n\nif ('CITGM' in process.env) {\n  files.push(\"!**/remote.test.ts\")\n}\n\nexport default {\n  extensions: {\n    ts: 'module',\n    mjs: true,\n  },\n  files,\n  workerThreads: false,\n  nodeArguments: ['--enable-source-maps'],\n}\n"
  },
  {
    "path": "cookbook/jwe.mjs",
    "content": "export default [\n  {\n    title:\n      'https://www.rfc-editor.org/rfc/rfc7520#section-5.2 - Key Encryption using RSA-OAEP with AES-GCM',\n    input: {\n      plaintext:\n        'You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.',\n      key: {\n        kty: 'RSA',\n        ext: false,\n        kid: 'samwise.gamgee@hobbiton.example',\n        use: 'enc',\n        n: 'wbdxI55VaanZXPY29Lg5hdmv2XhvqAhoxUkanfzf2-5zVUxa6prHRrI4pP1AhoqJRlZfYtWWd5mmHRG2pAHIlh0ySJ9wi0BioZBl1XP2e-C-FyXJGcTy0HdKQWlrfhTm42EW7Vv04r4gfao6uxjLGwfpGrZLarohiWCPnkNrg71S2CuNZSQBIPGjXfkmIy2tl_VWgGnL22GplyXj5YlBLdxXp3XeStsqo571utNfoUTU8E4qdzJ3U1DItoVkPGsMwlmmnJiwA7sXRItBCivR4M5qnZtdw-7v4WuR4779ubDuJ5nalMv2S66-RPcnFAzWSKxtBDnFJJDGIUe7Tzizjg1nms0Xq_yPub_UOlWn0ec85FCft1hACpWG8schrOBeNqHBODFskYpUc2LC5JA2TaPF2dA67dg1TTsC_FupfQ2kNGcE1LgprxKHcVWYQb86B-HozjHZcqtauBzFNV5tbTuB-TpkcvJfNcFLlH3b8mb-H_ox35FjqBSAjLKyoeqfKTpVjvXhd09knwgJf6VKq6UC418_TOljMVfFTWXUxlnfhOOnzW6HSSzD1c9WrCuVzsUMv54szidQ9wf1cYWf3g5qFDxDQKis99gcDaiCAwM3yEBIzuNeeCa5dartHDb1xEB_HcHSeYbghbMjGfasvKn0aZRsnTyC0xhWBlsolZE',\n        e: 'AQAB',\n        alg: 'RSA-OAEP',\n        d: 'n7fzJc3_WG59VEOBTkayzuSMM780OJQuZjN_KbH8lOZG25ZoA7T4Bxcc0xQn5oZE5uSCIwg91oCt0JvxPcpmqzaJZg1nirjcWZ-oBtVk7gCAWq-B3qhfF3izlbkosrzjHajIcY33HBhsy4_WerrXg4MDNE4HYojy68TcxT2LYQRxUOCf5TtJXvM8olexlSGtVnQnDRutxEUCwiewfmmrfveEogLx9EA-KMgAjTiISXxqIXQhWUQX1G7v_mV_Hr2YuImYcNcHkRvp9E7ook0876DhkO8v4UOZLwA1OlUX98mkoqwc58A_Y2lBYbVx1_s5lpPsEqbbH-nqIjh1fL0gdNfihLxnclWtW7pCztLnImZAyeCWAG7ZIfv-Rn9fLIv9jZ6r7r-MSH9sqbuziHN2grGjD_jfRluMHa0l84fFKl6bcqN1JWxPVhzNZo01yDF-1LiQnqUYSepPf6X3a2SOdkqBRiquE6EvLuSYIDpJq3jDIsgoL8Mo1LoomgiJxUwL_GWEOGu28gplyzm-9Q0U0nyhEf1uhSR8aJAQWAiFImWH5W_IQT9I7-yrindr_2fWQ_i1UgMsGzA7aOGzZfPljRy6z-tY_KuBG00-28S_aWvjyUc-Alp8AUyKjBZ-7CWH32fGWK48j1t-zomrwjL_mnhsPbGs0c9WsWgRzI-K8gE',\n        p: '7_2v3OQZzlPFcHyYfLABQ3XP85Es4hCdwCkbDeltaUXgVy9l9etKghvM4hRkOvbb01kYVuLFmxIkCDtpi-zLCYAdXKrAK3PtSbtzld_XZ9nlsYa_QZWpXB_IrtFjVfdKUdMz94pHUhFGFj7nr6NNxfpiHSHWFE1zD_AC3mY46J961Y2LRnreVwAGNw53p07Db8yD_92pDa97vqcZOdgtybH9q6uma-RFNhO1AoiJhYZj69hjmMRXx-x56HO9cnXNbmzNSCFCKnQmn4GQLmRj9sfbZRqL94bbtE4_e0Zrpo8RNo8vxRLqQNwIy85fc6BRgBJomt8QdQvIgPgWCv5HoQ',\n        q: 'zqOHk1P6WN_rHuM7ZF1cXH0x6RuOHq67WuHiSknqQeefGBA9PWs6ZyKQCO-O6mKXtcgE8_Q_hA2kMRcKOcvHil1hqMCNSXlflM7WPRPZu2qCDcqssd_uMbP-DqYthH_EzwL9KnYoH7JQFxxmcv5An8oXUtTwk4knKjkIYGRuUwfQTus0w1NfjFAyxOOiAQ37ussIcE6C6ZSsM3n41UlbJ7TCqewzVJaPJN5cxjySPZPD3Vp01a9YgAD6a3IIaKJdIxJS1ImnfPevSJQBE79-EXe2kSwVgOzvt-gsmM29QQ8veHy4uAqca5dZzMs7hkkHtw1z0jHV90epQJJlXXnH8Q',\n        dp: '19oDkBh1AXelMIxQFm2zZTqUhAzCIr4xNIGEPNoDt1jK83_FJA-xnx5kA7-1erdHdms_Ef67HsONNv5A60JaR7w8LHnDiBGnjdaUmmuO8XAxQJ_ia5mxjxNjS6E2yD44USo2JmHvzeeNczq25elqbTPLhUpGo1IZuG72FZQ5gTjXoTXC2-xtCDEUZfaUNh4IeAipfLugbpe0JAFlFfrTDAMUFpC3iXjxqzbEanflwPvj6V9iDSgjj8SozSM0dLtxvu0LIeIQAeEgT_yXcrKGmpKdSO08kLBx8VUjkbv_3Pn20Gyu2YEuwpFlM_H1NikuxJNKFGmnAq9LcnwwT0jvoQ',\n        dq: 'S6p59KrlmzGzaQYQM3o0XfHCGvfqHLYjCO557HYQf72O9kLMCfd_1VBEqeD-1jjwELKDjck8kOBl5UvohK1oDfSP1DleAy-cnmL29DqWmhgwM1ip0CCNmkmsmDSlqkUXDi6sAaZuntyukyflI-qSQ3C_BafPyFaKrt1fgdyEwYa08pESKwwWisy7KnmoUvaJ3SaHmohFS78TJ25cfc10wZ9hQNOrIChZlkiOdFCtxDqdmCqNacnhgE3bZQjGp3n83ODSz9zwJcSUvODlXBPc2AycH6Ci5yjbxt4Ppox_5pjm6xnQkiPgj01GpsUssMmBN7iHVsrE7N2iznBNCeOUIQ',\n        qi: 'FZhClBMywVVjnuUud-05qd5CYU0dK79akAgy9oX6RX6I3IIIPckCciRrokxglZn-omAY5CnCe4KdrnjFOT5YUZE7G_Pg44XgCXaarLQf4hl80oPEf6-jJ5Iy6wPRx7G2e8qLxnh9cOdf-kRqgOS3F48Ucvw3ma5V6KGMwQqWFeV31XtZ8l5cVI-I3NzBS7qltpUVgz2Ju021eyc7IlqgzR98qKONl27DuEES0aK0WE97jnsyO27Yp88Wa2RiBrEocM89QZI1seJiGDizHRUP4UZxw9zsXww46wy0P6f9grnYp7t8LkyDDk8eoI4KX6SNMNVcyVS9IWjlq8EzqZEKIA',\n      },\n      alg: 'RSA-OAEP',\n      enc: 'A256GCM',\n    },\n    generated: {\n      cek: 'mYMfsggkTAm0TbvtlFh2hyoXnbEzJQjMxmgLN3d8xXA',\n      iv: '-nBoKLH0YkLZPSI9',\n    },\n    encrypting_key: {},\n    encrypting_content: {\n      protected: {\n        alg: 'RSA-OAEP',\n        kid: 'samwise.gamgee@hobbiton.example',\n        enc: 'A256GCM',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJSU0EtT0FFUCIsImtpZCI6InNhbXdpc2UuZ2FtZ2VlQGhvYmJpdG9uLmV4YW1wbGUiLCJlbmMiOiJBMjU2R0NNIn0.rT99rwrBTbTI7IJM8fU3Eli7226HEB7IchCxNuh7lCiud48LxeolRdtFF4nzQibeYOl5S_PJsAXZwSXtDePz9hk-BbtsTBqC2UsPOdwjC9NhNupNNu9uHIVftDyucvI6hvALeZ6OGnhNV4v1zx2k7O1D89mAzfw-_kT3tkuorpDU-CpBENfIHX1Q58-Aad3FzMuo3Fn9buEP2yXakLXYa15BUXQsupM4A1GD4_H4Bd7V3u9h8Gkg8BpxKdUV9ScfJQTcYm6eJEBz3aSwIaK4T3-dwWpuBOhROQXBosJzS1asnuHtVMt2pKIIfux5BC6huIvmY7kzV7W7aIUrpYm_3H4zYvyMeq5pGqFmW2k8zpO878TRlZx7pZfPYDSXZyS0CfKKkMozT_qiCwZTSz4duYnt8hS4Z9sGthXn9uDqd6wycMagnQfOTs_lycTWmY-aqWVDKhjYNRf03NiwRtb5BE-tOdFwCASQj3uuAgPGrO2AWBe38UjQb0lvXn1SpyvYZ3WFc7WOJYaTa7A8DRn6MC6T-xDmMuxC0G7S2rscw5lQQU06MvZTlFOt0UvfuKBa03cxA_nIBIhLMjY2kOTxQMmpDPTr6Cbo8aKaOnx6ASE5Jx9paBpnNmOOKH35j_QlrQhDWUN6A2Gg8iFayJ69xDEdHAVCGRzN3woEI2ozDRs.-nBoKLH0YkLZPSI9.o4k2cnGN8rSSw3IDo1YuySkqeS_t2m1GXklSgqBdpACm6UJuJowOHC5ytjqYgRL-I-soPlwqMUf4UgRWWeaOGNw6vGW-xyM01lTYxrXfVzIIaRdhYtEMRBvBWbEwP7ua1DRfvaOjgZv6Ifa3brcAM64d8p5lhhNcizPersuhw5f-pGYzseva-TUaL8iWnctc-sSwy7SQmRkfhDjwbz0fz6kFovEgj64X1I5s7E6GLp5fnbYGLa1QUiML7Cc2GxgvI7zqWo0YIEc7aCflLG1-8BboVWFdZKLK9vNoycrYHumwzKluLWEbSVmaPpOslY2n525DxDfWaVFUfKQxMF56vn4B9QMpWAbnypNimbM8zVOw.UCGiqJxhBI3IFVdPalHHvA',\n      json: {\n        recipients: [\n          {\n            encrypted_key:\n              'rT99rwrBTbTI7IJM8fU3Eli7226HEB7IchCxNuh7lCiud48LxeolRdtFF4nzQibeYOl5S_PJsAXZwSXtDePz9hk-BbtsTBqC2UsPOdwjC9NhNupNNu9uHIVftDyucvI6hvALeZ6OGnhNV4v1zx2k7O1D89mAzfw-_kT3tkuorpDU-CpBENfIHX1Q58-Aad3FzMuo3Fn9buEP2yXakLXYa15BUXQsupM4A1GD4_H4Bd7V3u9h8Gkg8BpxKdUV9ScfJQTcYm6eJEBz3aSwIaK4T3-dwWpuBOhROQXBosJzS1asnuHtVMt2pKIIfux5BC6huIvmY7kzV7W7aIUrpYm_3H4zYvyMeq5pGqFmW2k8zpO878TRlZx7pZfPYDSXZyS0CfKKkMozT_qiCwZTSz4duYnt8hS4Z9sGthXn9uDqd6wycMagnQfOTs_lycTWmY-aqWVDKhjYNRf03NiwRtb5BE-tOdFwCASQj3uuAgPGrO2AWBe38UjQb0lvXn1SpyvYZ3WFc7WOJYaTa7A8DRn6MC6T-xDmMuxC0G7S2rscw5lQQU06MvZTlFOt0UvfuKBa03cxA_nIBIhLMjY2kOTxQMmpDPTr6Cbo8aKaOnx6ASE5Jx9paBpnNmOOKH35j_QlrQhDWUN6A2Gg8iFayJ69xDEdHAVCGRzN3woEI2ozDRs',\n          },\n        ],\n        protected:\n          'eyJhbGciOiJSU0EtT0FFUCIsImtpZCI6InNhbXdpc2UuZ2FtZ2VlQGhvYmJpdG9uLmV4YW1wbGUiLCJlbmMiOiJBMjU2R0NNIn0',\n        iv: '-nBoKLH0YkLZPSI9',\n        ciphertext:\n          'o4k2cnGN8rSSw3IDo1YuySkqeS_t2m1GXklSgqBdpACm6UJuJowOHC5ytjqYgRL-I-soPlwqMUf4UgRWWeaOGNw6vGW-xyM01lTYxrXfVzIIaRdhYtEMRBvBWbEwP7ua1DRfvaOjgZv6Ifa3brcAM64d8p5lhhNcizPersuhw5f-pGYzseva-TUaL8iWnctc-sSwy7SQmRkfhDjwbz0fz6kFovEgj64X1I5s7E6GLp5fnbYGLa1QUiML7Cc2GxgvI7zqWo0YIEc7aCflLG1-8BboVWFdZKLK9vNoycrYHumwzKluLWEbSVmaPpOslY2n525DxDfWaVFUfKQxMF56vn4B9QMpWAbnypNimbM8zVOw',\n        tag: 'UCGiqJxhBI3IFVdPalHHvA',\n      },\n      json_flat: {\n        protected:\n          'eyJhbGciOiJSU0EtT0FFUCIsImtpZCI6InNhbXdpc2UuZ2FtZ2VlQGhvYmJpdG9uLmV4YW1wbGUiLCJlbmMiOiJBMjU2R0NNIn0',\n        encrypted_key:\n          'rT99rwrBTbTI7IJM8fU3Eli7226HEB7IchCxNuh7lCiud48LxeolRdtFF4nzQibeYOl5S_PJsAXZwSXtDePz9hk-BbtsTBqC2UsPOdwjC9NhNupNNu9uHIVftDyucvI6hvALeZ6OGnhNV4v1zx2k7O1D89mAzfw-_kT3tkuorpDU-CpBENfIHX1Q58-Aad3FzMuo3Fn9buEP2yXakLXYa15BUXQsupM4A1GD4_H4Bd7V3u9h8Gkg8BpxKdUV9ScfJQTcYm6eJEBz3aSwIaK4T3-dwWpuBOhROQXBosJzS1asnuHtVMt2pKIIfux5BC6huIvmY7kzV7W7aIUrpYm_3H4zYvyMeq5pGqFmW2k8zpO878TRlZx7pZfPYDSXZyS0CfKKkMozT_qiCwZTSz4duYnt8hS4Z9sGthXn9uDqd6wycMagnQfOTs_lycTWmY-aqWVDKhjYNRf03NiwRtb5BE-tOdFwCASQj3uuAgPGrO2AWBe38UjQb0lvXn1SpyvYZ3WFc7WOJYaTa7A8DRn6MC6T-xDmMuxC0G7S2rscw5lQQU06MvZTlFOt0UvfuKBa03cxA_nIBIhLMjY2kOTxQMmpDPTr6Cbo8aKaOnx6ASE5Jx9paBpnNmOOKH35j_QlrQhDWUN6A2Gg8iFayJ69xDEdHAVCGRzN3woEI2ozDRs',\n        iv: '-nBoKLH0YkLZPSI9',\n        ciphertext:\n          'o4k2cnGN8rSSw3IDo1YuySkqeS_t2m1GXklSgqBdpACm6UJuJowOHC5ytjqYgRL-I-soPlwqMUf4UgRWWeaOGNw6vGW-xyM01lTYxrXfVzIIaRdhYtEMRBvBWbEwP7ua1DRfvaOjgZv6Ifa3brcAM64d8p5lhhNcizPersuhw5f-pGYzseva-TUaL8iWnctc-sSwy7SQmRkfhDjwbz0fz6kFovEgj64X1I5s7E6GLp5fnbYGLa1QUiML7Cc2GxgvI7zqWo0YIEc7aCflLG1-8BboVWFdZKLK9vNoycrYHumwzKluLWEbSVmaPpOslY2n525DxDfWaVFUfKQxMF56vn4B9QMpWAbnypNimbM8zVOw',\n        tag: 'UCGiqJxhBI3IFVdPalHHvA',\n      },\n    },\n  },\n  {\n    title:\n      'https://www.rfc-editor.org/rfc/rfc7520#section-5.3 - Key Wrap using PBES2-AES-KeyWrap with AES-CBC-HMAC-SHA2',\n    deterministic: true,\n    input: {\n      plaintext:\n        '{\"keys\":[{\"kty\":\"oct\",\"kid\":\"77c7e2b8-6e13-45cf-8672-617b5b45243a\",\"use\":\"enc\",\"alg\":\"A128GCM\",\"k\":\"XctOhJAkA-pD9Lh7ZgW_2A\"},{\"kty\":\"oct\",\"kid\":\"81b20965-8332-43d9-a468-82160ad91ac8\",\"use\":\"enc\",\"alg\":\"A128KW\",\"k\":\"GZy6sIZ6wl9NJOKB-jnmVQ\"},{\"kty\":\"oct\",\"kid\":\"18ec08e1-bfa9-4d95-b205-2b4dd1d4321d\",\"use\":\"enc\",\"alg\":\"A256GCMKW\",\"k\":\"qC57l_uxcm7Nm3K-ct4GFjx8tM1U8CZ0NLBvdQstiS8\"}]}',\n      pwd: 'entrap_o–peter_long–credit_tun',\n      alg: 'PBES2-HS512+A256KW',\n      enc: 'A128CBC-HS256',\n    },\n    generated: {\n      cek: 'uwsjJXaBK407Qaf0_zpcpmr1Cs0CC50hIUEyGNEt3m0',\n      iv: 'VBiCzVHNoLiR3F4V82uoTQ',\n    },\n    encrypting_key: {\n      salt: '8Q1SzinasR3xchYz6ZZcHA',\n      iteration_count: 8192,\n    },\n    encrypting_content: {\n      protected: {\n        alg: 'PBES2-HS512+A256KW',\n        p2s: '8Q1SzinasR3xchYz6ZZcHA',\n        p2c: 8192,\n        cty: 'jwk-set+json',\n        enc: 'A128CBC-HS256',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJQQkVTMi1IUzUxMitBMjU2S1ciLCJwMnMiOiI4UTFTemluYXNSM3hjaFl6NlpaY0hBIiwicDJjIjo4MTkyLCJjdHkiOiJqd2stc2V0K2pzb24iLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.d3qNhUWfqheyPp4H8sjOWsDYajoej4c5Je6rlUtFPWdgtURtmeDV1g.VBiCzVHNoLiR3F4V82uoTQ.23i-Tb1AV4n0WKVSSgcQrdg6GRqsUKxjruHXYsTHAJLZ2nsnGIX86vMXqIi6IRsfywCRFzLxEcZBRnTvG3nhzPk0GDD7FMyXhUHpDjEYCNA_XOmzg8yZR9oyjo6lTF6si4q9FZ2EhzgFQCLO_6h5EVg3vR75_hkBsnuoqoM3dwejXBtIodN84PeqMb6asmas_dpSsz7H10fC5ni9xIz424givB1YLldF6exVmL93R3fOoOJbmk2GBQZL_SEGllv2cQsBgeprARsaQ7Bq99tT80coH8ItBjgV08AtzXFFsx9qKvC982KLKdPQMTlVJKkqtV4Ru5LEVpBZXBnZrtViSOgyg6AiuwaS-rCrcD_ePOGSuxvgtrokAKYPqmXUeRdjFJwafkYEkiuDCV9vWGAi1DH2xTafhJwcmywIyzi4BqRpmdn_N-zl5tuJYyuvKhjKv6ihbsV_k1hJGPGAxJ6wUpmwC4PTQ2izEm0TuSE8oMKdTw8V3kobXZ77ulMwDs4p.0HlwodAhOCILG5SQ2LQ9dg',\n      json: {\n        recipients: [\n          {\n            encrypted_key: 'd3qNhUWfqheyPp4H8sjOWsDYajoej4c5Je6rlUtFPWdgtURtmeDV1g',\n          },\n        ],\n        protected:\n          'eyJhbGciOiJQQkVTMi1IUzUxMitBMjU2S1ciLCJwMnMiOiI4UTFTemluYXNSM3hjaFl6NlpaY0hBIiwicDJjIjo4MTkyLCJjdHkiOiJqd2stc2V0K2pzb24iLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0',\n        iv: 'VBiCzVHNoLiR3F4V82uoTQ',\n        ciphertext:\n          '23i-Tb1AV4n0WKVSSgcQrdg6GRqsUKxjruHXYsTHAJLZ2nsnGIX86vMXqIi6IRsfywCRFzLxEcZBRnTvG3nhzPk0GDD7FMyXhUHpDjEYCNA_XOmzg8yZR9oyjo6lTF6si4q9FZ2EhzgFQCLO_6h5EVg3vR75_hkBsnuoqoM3dwejXBtIodN84PeqMb6asmas_dpSsz7H10fC5ni9xIz424givB1YLldF6exVmL93R3fOoOJbmk2GBQZL_SEGllv2cQsBgeprARsaQ7Bq99tT80coH8ItBjgV08AtzXFFsx9qKvC982KLKdPQMTlVJKkqtV4Ru5LEVpBZXBnZrtViSOgyg6AiuwaS-rCrcD_ePOGSuxvgtrokAKYPqmXUeRdjFJwafkYEkiuDCV9vWGAi1DH2xTafhJwcmywIyzi4BqRpmdn_N-zl5tuJYyuvKhjKv6ihbsV_k1hJGPGAxJ6wUpmwC4PTQ2izEm0TuSE8oMKdTw8V3kobXZ77ulMwDs4p',\n        tag: '0HlwodAhOCILG5SQ2LQ9dg',\n      },\n      json_flat: {\n        protected:\n          'eyJhbGciOiJQQkVTMi1IUzUxMitBMjU2S1ciLCJwMnMiOiI4UTFTemluYXNSM3hjaFl6NlpaY0hBIiwicDJjIjo4MTkyLCJjdHkiOiJqd2stc2V0K2pzb24iLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0',\n        encrypted_key: 'd3qNhUWfqheyPp4H8sjOWsDYajoej4c5Je6rlUtFPWdgtURtmeDV1g',\n        iv: 'VBiCzVHNoLiR3F4V82uoTQ',\n        ciphertext:\n          '23i-Tb1AV4n0WKVSSgcQrdg6GRqsUKxjruHXYsTHAJLZ2nsnGIX86vMXqIi6IRsfywCRFzLxEcZBRnTvG3nhzPk0GDD7FMyXhUHpDjEYCNA_XOmzg8yZR9oyjo6lTF6si4q9FZ2EhzgFQCLO_6h5EVg3vR75_hkBsnuoqoM3dwejXBtIodN84PeqMb6asmas_dpSsz7H10fC5ni9xIz424givB1YLldF6exVmL93R3fOoOJbmk2GBQZL_SEGllv2cQsBgeprARsaQ7Bq99tT80coH8ItBjgV08AtzXFFsx9qKvC982KLKdPQMTlVJKkqtV4Ru5LEVpBZXBnZrtViSOgyg6AiuwaS-rCrcD_ePOGSuxvgtrokAKYPqmXUeRdjFJwafkYEkiuDCV9vWGAi1DH2xTafhJwcmywIyzi4BqRpmdn_N-zl5tuJYyuvKhjKv6ihbsV_k1hJGPGAxJ6wUpmwC4PTQ2izEm0TuSE8oMKdTw8V3kobXZ77ulMwDs4p',\n        tag: '0HlwodAhOCILG5SQ2LQ9dg',\n      },\n    },\n  },\n  {\n    title:\n      'https://www.rfc-editor.org/rfc/rfc7520#section-5.4 - Key Agreement with Key Wrapping using ECDH-ES and AES-KeyWrap with AES-GCM',\n    input: {\n      plaintext:\n        'You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.',\n      key: {\n        kty: 'EC',\n        ext: false,\n        kid: 'peregrin.took@tuckborough.example',\n        use: 'enc',\n        crv: 'P-384',\n        x: 'YU4rRUzdmVqmRtWOs2OpDE_T5fsNIodcG8G5FWPrTPMyxpzsSOGaQLpe2FpxBmu2',\n        y: 'A8-yxCHxkfBz3hKZfI1jUYMjUhsEveZ9THuwFjH2sCNdtksRJU7D5-SkgaFL1ETP',\n        d: 'iTx2pk7wW-GqJkHcEkFQb2EFyYcO7RugmaW3mRrQVAOUiPommT0IdnYK2xDlZh-j',\n      },\n      alg: 'ECDH-ES+A128KW',\n      enc: 'A128GCM',\n    },\n    generated: {\n      cek: 'Nou2ueKlP70ZXDbq9UrRwg',\n      iv: 'mH-G2zVqgztUtnW_',\n    },\n    encrypting_key: {\n      epk: {\n        kty: 'EC',\n        crv: 'P-384',\n        x: 'uBo4kHPw6kbjx5l0xowrd_oYzBmaz-GKFZu4xAFFkbYiWgutEK6iuEDsQ6wNdNg3',\n        y: 'sp3p5SGhZVC2faXumI-e9JU2Mo8KpoYrFDr5yPNVtW4PgEwZOyQTA-JdaY8tb7E0',\n        d: 'D5H4Y_5PSKZvhfVFbcCYJOtcGZygRgfZkpsBr59Icmmhe9sW6nkZ8WfwhinUfWJg',\n      },\n    },\n    encrypting_content: {\n      protected: {\n        alg: 'ECDH-ES+A128KW',\n        kid: 'peregrin.took@tuckborough.example',\n        epk: {\n          kty: 'EC',\n          crv: 'P-384',\n          x: 'uBo4kHPw6kbjx5l0xowrd_oYzBmaz-GKFZu4xAFFkbYiWgutEK6iuEDsQ6wNdNg3',\n          y: 'sp3p5SGhZVC2faXumI-e9JU2Mo8KpoYrFDr5yPNVtW4PgEwZOyQTA-JdaY8tb7E0',\n        },\n        enc: 'A128GCM',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImtpZCI6InBlcmVncmluLnRvb2tAdHVja2Jvcm91Z2guZXhhbXBsZSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMzg0IiwieCI6InVCbzRrSFB3Nmtiang1bDB4b3dyZF9vWXpCbWF6LUdLRlp1NHhBRkZrYllpV2d1dEVLNml1RURzUTZ3TmROZzMiLCJ5Ijoic3AzcDVTR2haVkMyZmFYdW1JLWU5SlUyTW84S3BvWXJGRHI1eVBOVnRXNFBnRXdaT3lRVEEtSmRhWTh0YjdFMCJ9LCJlbmMiOiJBMTI4R0NNIn0.0DJjBXri_kBcC46IkU5_Jk9BqaQeHdv2.mH-G2zVqgztUtnW_.tkZuOO9h95OgHJmkkrfLBisku8rGf6nzVxhRM3sVOhXgz5NJ76oID7lpnAi_cPWJRCjSpAaUZ5dOR3Spy7QuEkmKx8-3RCMhSYMzsXaEwDdXta9Mn5B7cCBoJKB0IgEnj_qfo1hIi-uEkUpOZ8aLTZGHfpl05jMwbKkTe2yK3mjF6SBAsgicQDVCkcY9BLluzx1RmC3ORXaM0JaHPB93YcdSDGgpgBWMVrNU1ErkjcMqMoT_wtCex3w03XdLkjXIuEr2hWgeP-nkUZTPU9EoGSPj6fAS-bSz87RCPrxZdj_iVyC6QWcqAu07WNhjzJEPc4jVntRJ6K53NgPQ5p99l3Z408OUqj4ioYezbS6vTPlQ.WuGzxmcreYjpHGJoa17EBg',\n      json: {\n        recipients: [\n          {\n            encrypted_key: '0DJjBXri_kBcC46IkU5_Jk9BqaQeHdv2',\n          },\n        ],\n        protected:\n          'eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImtpZCI6InBlcmVncmluLnRvb2tAdHVja2Jvcm91Z2guZXhhbXBsZSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMzg0IiwieCI6InVCbzRrSFB3Nmtiang1bDB4b3dyZF9vWXpCbWF6LUdLRlp1NHhBRkZrYllpV2d1dEVLNml1RURzUTZ3TmROZzMiLCJ5Ijoic3AzcDVTR2haVkMyZmFYdW1JLWU5SlUyTW84S3BvWXJGRHI1eVBOVnRXNFBnRXdaT3lRVEEtSmRhWTh0YjdFMCJ9LCJlbmMiOiJBMTI4R0NNIn0',\n        iv: 'mH-G2zVqgztUtnW_',\n        ciphertext:\n          'tkZuOO9h95OgHJmkkrfLBisku8rGf6nzVxhRM3sVOhXgz5NJ76oID7lpnAi_cPWJRCjSpAaUZ5dOR3Spy7QuEkmKx8-3RCMhSYMzsXaEwDdXta9Mn5B7cCBoJKB0IgEnj_qfo1hIi-uEkUpOZ8aLTZGHfpl05jMwbKkTe2yK3mjF6SBAsgicQDVCkcY9BLluzx1RmC3ORXaM0JaHPB93YcdSDGgpgBWMVrNU1ErkjcMqMoT_wtCex3w03XdLkjXIuEr2hWgeP-nkUZTPU9EoGSPj6fAS-bSz87RCPrxZdj_iVyC6QWcqAu07WNhjzJEPc4jVntRJ6K53NgPQ5p99l3Z408OUqj4ioYezbS6vTPlQ',\n        tag: 'WuGzxmcreYjpHGJoa17EBg',\n      },\n      json_flat: {\n        protected:\n          'eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImtpZCI6InBlcmVncmluLnRvb2tAdHVja2Jvcm91Z2guZXhhbXBsZSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMzg0IiwieCI6InVCbzRrSFB3Nmtiang1bDB4b3dyZF9vWXpCbWF6LUdLRlp1NHhBRkZrYllpV2d1dEVLNml1RURzUTZ3TmROZzMiLCJ5Ijoic3AzcDVTR2haVkMyZmFYdW1JLWU5SlUyTW84S3BvWXJGRHI1eVBOVnRXNFBnRXdaT3lRVEEtSmRhWTh0YjdFMCJ9LCJlbmMiOiJBMTI4R0NNIn0',\n        encrypted_key: '0DJjBXri_kBcC46IkU5_Jk9BqaQeHdv2',\n        iv: 'mH-G2zVqgztUtnW_',\n        ciphertext:\n          'tkZuOO9h95OgHJmkkrfLBisku8rGf6nzVxhRM3sVOhXgz5NJ76oID7lpnAi_cPWJRCjSpAaUZ5dOR3Spy7QuEkmKx8-3RCMhSYMzsXaEwDdXta9Mn5B7cCBoJKB0IgEnj_qfo1hIi-uEkUpOZ8aLTZGHfpl05jMwbKkTe2yK3mjF6SBAsgicQDVCkcY9BLluzx1RmC3ORXaM0JaHPB93YcdSDGgpgBWMVrNU1ErkjcMqMoT_wtCex3w03XdLkjXIuEr2hWgeP-nkUZTPU9EoGSPj6fAS-bSz87RCPrxZdj_iVyC6QWcqAu07WNhjzJEPc4jVntRJ6K53NgPQ5p99l3Z408OUqj4ioYezbS6vTPlQ',\n        tag: 'WuGzxmcreYjpHGJoa17EBg',\n      },\n    },\n  },\n  {\n    title:\n      'https://www.rfc-editor.org/rfc/rfc7520#section-5.5 - Key Agreement using ECDH-ES with AES-CBC-HMAC-SHA2',\n    input: {\n      plaintext:\n        'You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.',\n      key: {\n        kty: 'EC',\n        ext: false,\n        kid: 'meriadoc.brandybuck@buckland.example',\n        use: 'enc',\n        crv: 'P-256',\n        x: 'Ze2loSV3wrroKUN_4zhwGhCqo3Xhu1td4QjeQ5wIVR0',\n        y: 'HlLtdXARY_f55A3fnzQbPcm6hgr34Mp8p-nuzQCE0Zw',\n        d: 'r_kHyZ-a06rmxM3yESK84r1otSg-aQcVStkRhA-iCM8',\n      },\n      alg: 'ECDH-ES',\n      enc: 'A128CBC-HS256',\n    },\n    generated: {\n      iv: 'yc9N8v5sYyv3iGQT926IUg',\n    },\n    encrypting_key: {\n      epk: {\n        kty: 'EC',\n        crv: 'P-256',\n        x: 'mPUKT_bAWGHIhg0TpjjqVsP1rXWQu_vwVOHHtNkdYoA',\n        y: '8BQAsImGeAS46fyWw5MhYfGTT0IjBpFw2SS34Dv4Irs',\n        d: 'AtH35vJsQ9SGjYfOsjUxYXQKrPH3FjZHmEtSKoSN8cM',\n      },\n      cek: 'hzHdlfQIAEehb8Hrd_mFRhKsKLEzPfshfXs9l6areCc',\n    },\n    encrypting_content: {\n      protected: {\n        alg: 'ECDH-ES',\n        kid: 'meriadoc.brandybuck@buckland.example',\n        epk: {\n          kty: 'EC',\n          crv: 'P-256',\n          x: 'mPUKT_bAWGHIhg0TpjjqVsP1rXWQu_vwVOHHtNkdYoA',\n          y: '8BQAsImGeAS46fyWw5MhYfGTT0IjBpFw2SS34Dv4Irs',\n        },\n        enc: 'A128CBC-HS256',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJFQ0RILUVTIiwia2lkIjoibWVyaWFkb2MuYnJhbmR5YnVja0BidWNrbGFuZC5leGFtcGxlIiwiZXBrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoibVBVS1RfYkFXR0hJaGcwVHBqanFWc1AxclhXUXVfdndWT0hIdE5rZFlvQSIsInkiOiI4QlFBc0ltR2VBUzQ2ZnlXdzVNaFlmR1RUMElqQnBGdzJTUzM0RHY0SXJzIn0sImVuYyI6IkExMjhDQkMtSFMyNTYifQ..yc9N8v5sYyv3iGQT926IUg.BoDlwPnTypYq-ivjmQvAYJLb5Q6l-F3LIgQomlz87yW4OPKbWE1zSTEFjDfhU9IPIOSA9Bml4m7iDFwA-1ZXvHteLDtw4R1XRGMEsDIqAYtskTTmzmzNa-_q4F_evAPUmwlO-ZG45Mnq4uhM1fm_D9rBtWolqZSF3xGNNkpOMQKF1Cl8i8wjzRli7-IXgyirlKQsbhhqRzkv8IcY6aHl24j03C-AR2le1r7URUhArM79BY8soZU0lzwI-sD5PZ3l4NDCCei9XkoIAfsXJWmySPoeRb2Ni5UZL4mYpvKDiwmyzGd65KqVw7MsFfI_K767G9C9Azp73gKZD0DyUn1mn0WW5LmyX_yJ-3AROq8p1WZBfG-ZyJ6195_JGG2m9Csg.WCCkNa-x4BeB9hIDIfFuhg',\n      json: {\n        protected:\n          'eyJhbGciOiJFQ0RILUVTIiwia2lkIjoibWVyaWFkb2MuYnJhbmR5YnVja0BidWNrbGFuZC5leGFtcGxlIiwiZXBrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoibVBVS1RfYkFXR0hJaGcwVHBqanFWc1AxclhXUXVfdndWT0hIdE5rZFlvQSIsInkiOiI4QlFBc0ltR2VBUzQ2ZnlXdzVNaFlmR1RUMElqQnBGdzJTUzM0RHY0SXJzIn0sImVuYyI6IkExMjhDQkMtSFMyNTYifQ',\n        iv: 'yc9N8v5sYyv3iGQT926IUg',\n        ciphertext:\n          'BoDlwPnTypYq-ivjmQvAYJLb5Q6l-F3LIgQomlz87yW4OPKbWE1zSTEFjDfhU9IPIOSA9Bml4m7iDFwA-1ZXvHteLDtw4R1XRGMEsDIqAYtskTTmzmzNa-_q4F_evAPUmwlO-ZG45Mnq4uhM1fm_D9rBtWolqZSF3xGNNkpOMQKF1Cl8i8wjzRli7-IXgyirlKQsbhhqRzkv8IcY6aHl24j03C-AR2le1r7URUhArM79BY8soZU0lzwI-sD5PZ3l4NDCCei9XkoIAfsXJWmySPoeRb2Ni5UZL4mYpvKDiwmyzGd65KqVw7MsFfI_K767G9C9Azp73gKZD0DyUn1mn0WW5LmyX_yJ-3AROq8p1WZBfG-ZyJ6195_JGG2m9Csg',\n        tag: 'WCCkNa-x4BeB9hIDIfFuhg',\n      },\n      json_flat: {\n        protected:\n          'eyJhbGciOiJFQ0RILUVTIiwia2lkIjoibWVyaWFkb2MuYnJhbmR5YnVja0BidWNrbGFuZC5leGFtcGxlIiwiZXBrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoibVBVS1RfYkFXR0hJaGcwVHBqanFWc1AxclhXUXVfdndWT0hIdE5rZFlvQSIsInkiOiI4QlFBc0ltR2VBUzQ2ZnlXdzVNaFlmR1RUMElqQnBGdzJTUzM0RHY0SXJzIn0sImVuYyI6IkExMjhDQkMtSFMyNTYifQ',\n        iv: 'yc9N8v5sYyv3iGQT926IUg',\n        ciphertext:\n          'BoDlwPnTypYq-ivjmQvAYJLb5Q6l-F3LIgQomlz87yW4OPKbWE1zSTEFjDfhU9IPIOSA9Bml4m7iDFwA-1ZXvHteLDtw4R1XRGMEsDIqAYtskTTmzmzNa-_q4F_evAPUmwlO-ZG45Mnq4uhM1fm_D9rBtWolqZSF3xGNNkpOMQKF1Cl8i8wjzRli7-IXgyirlKQsbhhqRzkv8IcY6aHl24j03C-AR2le1r7URUhArM79BY8soZU0lzwI-sD5PZ3l4NDCCei9XkoIAfsXJWmySPoeRb2Ni5UZL4mYpvKDiwmyzGd65KqVw7MsFfI_K767G9C9Azp73gKZD0DyUn1mn0WW5LmyX_yJ-3AROq8p1WZBfG-ZyJ6195_JGG2m9Csg',\n        tag: 'WCCkNa-x4BeB9hIDIfFuhg',\n      },\n    },\n  },\n  {\n    title:\n      'https://www.rfc-editor.org/rfc/rfc7520#section-5.6 - Direction Encryption using AES-GCM',\n    deterministic: true,\n    input: {\n      plaintext:\n        'You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.',\n      key: {\n        kty: 'oct',\n        ext: false,\n        kid: '77c7e2b8-6e13-45cf-8672-617b5b45243a',\n        use: 'enc',\n        alg: 'A128GCM',\n        k: 'XctOhJAkA-pD9Lh7ZgW_2A',\n      },\n      alg: 'dir',\n      enc: 'A128GCM',\n    },\n    generated: {\n      iv: 'refa467QzzKx6QAB',\n    },\n    encrypting_content: {\n      protected: {\n        alg: 'dir',\n        kid: '77c7e2b8-6e13-45cf-8672-617b5b45243a',\n        enc: 'A128GCM',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJkaXIiLCJraWQiOiI3N2M3ZTJiOC02ZTEzLTQ1Y2YtODY3Mi02MTdiNWI0NTI0M2EiLCJlbmMiOiJBMTI4R0NNIn0..refa467QzzKx6QAB.JW_i_f52hww_ELQPGaYyeAB6HYGcR559l9TYnSovc23XJoBcW29rHP8yZOZG7YhLpT1bjFuvZPjQS-m0IFtVcXkZXdH_lr_FrdYt9HRUYkshtrMmIUAyGmUnd9zMDB2n0cRDIHAzFVeJUDxkUwVAE7_YGRPdcqMyiBoCO-FBdE-Nceb4h3-FtBP-c_BIwCPTjb9o0SbdcdREEMJMyZBH8ySWMVi1gPD9yxi-aQpGbSv_F9N4IZAxscj5g-NJsUPbjk29-s7LJAGb15wEBtXphVCgyy53CoIKLHHeJHXex45Uz9aKZSRSInZI-wjsY0yu3cT4_aQ3i1o-tiE-F8Ios61EKgyIQ4CWao8PFMj8TTnp.vbb32Xvllea2OtmHAdccRQ',\n      json: {\n        protected:\n          'eyJhbGciOiJkaXIiLCJraWQiOiI3N2M3ZTJiOC02ZTEzLTQ1Y2YtODY3Mi02MTdiNWI0NTI0M2EiLCJlbmMiOiJBMTI4R0NNIn0',\n        iv: 'refa467QzzKx6QAB',\n        ciphertext:\n          'JW_i_f52hww_ELQPGaYyeAB6HYGcR559l9TYnSovc23XJoBcW29rHP8yZOZG7YhLpT1bjFuvZPjQS-m0IFtVcXkZXdH_lr_FrdYt9HRUYkshtrMmIUAyGmUnd9zMDB2n0cRDIHAzFVeJUDxkUwVAE7_YGRPdcqMyiBoCO-FBdE-Nceb4h3-FtBP-c_BIwCPTjb9o0SbdcdREEMJMyZBH8ySWMVi1gPD9yxi-aQpGbSv_F9N4IZAxscj5g-NJsUPbjk29-s7LJAGb15wEBtXphVCgyy53CoIKLHHeJHXex45Uz9aKZSRSInZI-wjsY0yu3cT4_aQ3i1o-tiE-F8Ios61EKgyIQ4CWao8PFMj8TTnp',\n        tag: 'vbb32Xvllea2OtmHAdccRQ',\n      },\n      json_flat: {\n        protected:\n          'eyJhbGciOiJkaXIiLCJraWQiOiI3N2M3ZTJiOC02ZTEzLTQ1Y2YtODY3Mi02MTdiNWI0NTI0M2EiLCJlbmMiOiJBMTI4R0NNIn0',\n        iv: 'refa467QzzKx6QAB',\n        ciphertext:\n          'JW_i_f52hww_ELQPGaYyeAB6HYGcR559l9TYnSovc23XJoBcW29rHP8yZOZG7YhLpT1bjFuvZPjQS-m0IFtVcXkZXdH_lr_FrdYt9HRUYkshtrMmIUAyGmUnd9zMDB2n0cRDIHAzFVeJUDxkUwVAE7_YGRPdcqMyiBoCO-FBdE-Nceb4h3-FtBP-c_BIwCPTjb9o0SbdcdREEMJMyZBH8ySWMVi1gPD9yxi-aQpGbSv_F9N4IZAxscj5g-NJsUPbjk29-s7LJAGb15wEBtXphVCgyy53CoIKLHHeJHXex45Uz9aKZSRSInZI-wjsY0yu3cT4_aQ3i1o-tiE-F8Ios61EKgyIQ4CWao8PFMj8TTnp',\n        tag: 'vbb32Xvllea2OtmHAdccRQ',\n      },\n    },\n  },\n  {\n    title:\n      'https://www.rfc-editor.org/rfc/rfc7520#section-5.6 - Key Wrap using AES-GCM KeyWrap with AES-CBC-HMAC-SHA2',\n    deterministic: true,\n    input: {\n      plaintext:\n        'You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.',\n      key: {\n        kty: 'oct',\n        ext: false,\n        kid: '18ec08e1-bfa9-4d95-b205-2b4dd1d4321d',\n        use: 'enc',\n        alg: 'A256GCMKW',\n        k: 'qC57l_uxcm7Nm3K-ct4GFjx8tM1U8CZ0NLBvdQstiS8',\n      },\n      alg: 'A256GCMKW',\n      enc: 'A128CBC-HS256',\n    },\n    generated: {\n      cek: 'UWxARpat23nL9ReIj4WG3D1ee9I4r-Mv5QLuFXdy_rE',\n      iv: 'gz6NjyEFNm_vm8Gj6FwoFQ',\n    },\n    encrypting_key: {\n      iv: 'KkYT0GX_2jHlfqN_',\n      tag: 'kfPduVQ3T3H6vnewt--ksw',\n    },\n    encrypting_content: {\n      protected: {\n        alg: 'A256GCMKW',\n        kid: '18ec08e1-bfa9-4d95-b205-2b4dd1d4321d',\n        tag: 'kfPduVQ3T3H6vnewt--ksw',\n        iv: 'KkYT0GX_2jHlfqN_',\n        enc: 'A128CBC-HS256',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJBMjU2R0NNS1ciLCJraWQiOiIxOGVjMDhlMS1iZmE5LTRkOTUtYjIwNS0yYjRkZDFkNDMyMWQiLCJ0YWciOiJrZlBkdVZRM1QzSDZ2bmV3dC0ta3N3IiwiaXYiOiJLa1lUMEdYXzJqSGxmcU5fIiwiZW5jIjoiQTEyOENCQy1IUzI1NiJ9.lJf3HbOApxMEBkCMOoTnnABxs_CvTWUmZQ2ElLvYNok.gz6NjyEFNm_vm8Gj6FwoFQ.Jf5p9-ZhJlJy_IQ_byKFmI0Ro7w7G1QiaZpI8OaiVgD8EqoDZHyFKFBupS8iaEeVIgMqWmsuJKuoVgzR3YfzoMd3GxEm3VxNhzWyWtZKX0gxKdy6HgLvqoGNbZCzLjqcpDiF8q2_62EVAbr2uSc2oaxFmFuIQHLcqAHxy51449xkjZ7ewzZaGV3eFqhpco8o4DijXaG5_7kp3h2cajRfDgymuxUbWgLqaeNQaJtvJmSMFuEOSAzw9Hdeb6yhdTynCRmu-kqtO5Dec4lT2OMZKpnxc_F1_4yDJFcqb5CiDSmA-psB2k0JtjxAj4UPI61oONK7zzFIu4gBfjJCndsZfdvG7h8wGjV98QhrKEnR7xKZ3KCr0_qR1B-gxpNk3xWU.DKW7jrb4WaRSNfbXVPlT5g',\n      json: {\n        recipients: [\n          {\n            encrypted_key: 'lJf3HbOApxMEBkCMOoTnnABxs_CvTWUmZQ2ElLvYNok',\n          },\n        ],\n        protected:\n          'eyJhbGciOiJBMjU2R0NNS1ciLCJraWQiOiIxOGVjMDhlMS1iZmE5LTRkOTUtYjIwNS0yYjRkZDFkNDMyMWQiLCJ0YWciOiJrZlBkdVZRM1QzSDZ2bmV3dC0ta3N3IiwiaXYiOiJLa1lUMEdYXzJqSGxmcU5fIiwiZW5jIjoiQTEyOENCQy1IUzI1NiJ9',\n        iv: 'gz6NjyEFNm_vm8Gj6FwoFQ',\n        ciphertext:\n          'Jf5p9-ZhJlJy_IQ_byKFmI0Ro7w7G1QiaZpI8OaiVgD8EqoDZHyFKFBupS8iaEeVIgMqWmsuJKuoVgzR3YfzoMd3GxEm3VxNhzWyWtZKX0gxKdy6HgLvqoGNbZCzLjqcpDiF8q2_62EVAbr2uSc2oaxFmFuIQHLcqAHxy51449xkjZ7ewzZaGV3eFqhpco8o4DijXaG5_7kp3h2cajRfDgymuxUbWgLqaeNQaJtvJmSMFuEOSAzw9Hdeb6yhdTynCRmu-kqtO5Dec4lT2OMZKpnxc_F1_4yDJFcqb5CiDSmA-psB2k0JtjxAj4UPI61oONK7zzFIu4gBfjJCndsZfdvG7h8wGjV98QhrKEnR7xKZ3KCr0_qR1B-gxpNk3xWU',\n        tag: 'DKW7jrb4WaRSNfbXVPlT5g',\n      },\n      json_flat: {\n        protected:\n          'eyJhbGciOiJBMjU2R0NNS1ciLCJraWQiOiIxOGVjMDhlMS1iZmE5LTRkOTUtYjIwNS0yYjRkZDFkNDMyMWQiLCJ0YWciOiJrZlBkdVZRM1QzSDZ2bmV3dC0ta3N3IiwiaXYiOiJLa1lUMEdYXzJqSGxmcU5fIiwiZW5jIjoiQTEyOENCQy1IUzI1NiJ9',\n        encrypted_key: 'lJf3HbOApxMEBkCMOoTnnABxs_CvTWUmZQ2ElLvYNok',\n        iv: 'gz6NjyEFNm_vm8Gj6FwoFQ',\n        ciphertext:\n          'Jf5p9-ZhJlJy_IQ_byKFmI0Ro7w7G1QiaZpI8OaiVgD8EqoDZHyFKFBupS8iaEeVIgMqWmsuJKuoVgzR3YfzoMd3GxEm3VxNhzWyWtZKX0gxKdy6HgLvqoGNbZCzLjqcpDiF8q2_62EVAbr2uSc2oaxFmFuIQHLcqAHxy51449xkjZ7ewzZaGV3eFqhpco8o4DijXaG5_7kp3h2cajRfDgymuxUbWgLqaeNQaJtvJmSMFuEOSAzw9Hdeb6yhdTynCRmu-kqtO5Dec4lT2OMZKpnxc_F1_4yDJFcqb5CiDSmA-psB2k0JtjxAj4UPI61oONK7zzFIu4gBfjJCndsZfdvG7h8wGjV98QhrKEnR7xKZ3KCr0_qR1B-gxpNk3xWU',\n        tag: 'DKW7jrb4WaRSNfbXVPlT5g',\n      },\n    },\n  },\n  {\n    title:\n      'https://www.rfc-editor.org/rfc/rfc7520#section-5.8 - Key Wrap using AES-KeyWrap with AES-GCM',\n    deterministic: true,\n    input: {\n      plaintext:\n        'You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.',\n      key: {\n        kty: 'oct',\n        ext: false,\n        kid: '81b20965-8332-43d9-a468-82160ad91ac8',\n        use: 'enc',\n        alg: 'A128KW',\n        k: 'GZy6sIZ6wl9NJOKB-jnmVQ',\n      },\n      alg: 'A128KW',\n      enc: 'A128GCM',\n    },\n    generated: {\n      cek: 'aY5_Ghmk9KxWPBLu_glx1w',\n      iv: 'Qx0pmsDa8KnJc9Jo',\n    },\n    encrypting_key: {},\n    encrypting_content: {\n      protected: {\n        alg: 'A128KW',\n        kid: '81b20965-8332-43d9-a468-82160ad91ac8',\n        enc: 'A128GCM',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIn0.CBI6oDw8MydIx1IBntf_lQcw2MmJKIQx.Qx0pmsDa8KnJc9Jo.AwliP-KmWgsZ37BvzCefNen6VTbRK3QMA4TkvRkH0tP1bTdhtFJgJxeVmJkLD61A1hnWGetdg11c9ADsnWgL56NyxwSYjU1ZEHcGkd3EkU0vjHi9gTlb90qSYFfeF0LwkcTtjbYKCsiNJQkcIp1yeM03OmuiYSoYJVSpf7ej6zaYcMv3WwdxDFl8REwOhNImk2Xld2JXq6BR53TSFkyT7PwVLuq-1GwtGHlQeg7gDT6xW0JqHDPn_H-puQsmthc9Zg0ojmJfqqFvETUxLAF-KjcBTS5dNy6egwkYtOt8EIHK-oEsKYtZRaa8Z7MOZ7UGxGIMvEmxrGCPeJa14slv2-gaqK0kEThkaSqdYw0FkQZF.ER7MWJZ1FBI_NKvn7Zb1Lw',\n      json: {\n        recipients: [\n          {\n            encrypted_key: 'CBI6oDw8MydIx1IBntf_lQcw2MmJKIQx',\n          },\n        ],\n        protected:\n          'eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIn0',\n        iv: 'Qx0pmsDa8KnJc9Jo',\n        ciphertext:\n          'AwliP-KmWgsZ37BvzCefNen6VTbRK3QMA4TkvRkH0tP1bTdhtFJgJxeVmJkLD61A1hnWGetdg11c9ADsnWgL56NyxwSYjU1ZEHcGkd3EkU0vjHi9gTlb90qSYFfeF0LwkcTtjbYKCsiNJQkcIp1yeM03OmuiYSoYJVSpf7ej6zaYcMv3WwdxDFl8REwOhNImk2Xld2JXq6BR53TSFkyT7PwVLuq-1GwtGHlQeg7gDT6xW0JqHDPn_H-puQsmthc9Zg0ojmJfqqFvETUxLAF-KjcBTS5dNy6egwkYtOt8EIHK-oEsKYtZRaa8Z7MOZ7UGxGIMvEmxrGCPeJa14slv2-gaqK0kEThkaSqdYw0FkQZF',\n        tag: 'ER7MWJZ1FBI_NKvn7Zb1Lw',\n      },\n      json_flat: {\n        protected:\n          'eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIn0',\n        encrypted_key: 'CBI6oDw8MydIx1IBntf_lQcw2MmJKIQx',\n        iv: 'Qx0pmsDa8KnJc9Jo',\n        ciphertext:\n          'AwliP-KmWgsZ37BvzCefNen6VTbRK3QMA4TkvRkH0tP1bTdhtFJgJxeVmJkLD61A1hnWGetdg11c9ADsnWgL56NyxwSYjU1ZEHcGkd3EkU0vjHi9gTlb90qSYFfeF0LwkcTtjbYKCsiNJQkcIp1yeM03OmuiYSoYJVSpf7ej6zaYcMv3WwdxDFl8REwOhNImk2Xld2JXq6BR53TSFkyT7PwVLuq-1GwtGHlQeg7gDT6xW0JqHDPn_H-puQsmthc9Zg0ojmJfqqFvETUxLAF-KjcBTS5dNy6egwkYtOt8EIHK-oEsKYtZRaa8Z7MOZ7UGxGIMvEmxrGCPeJa14slv2-gaqK0kEThkaSqdYw0FkQZF',\n        tag: 'ER7MWJZ1FBI_NKvn7Zb1Lw',\n      },\n    },\n  },\n  {\n    title: 'https://www.rfc-editor.org/rfc/rfc7520#section-5.9 - Compressed Content',\n    deterministic: false, // https://www.rfc-editor.org/errata/eid7680\n    input: {\n      plaintext:\n        'You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.',\n      key: {\n        kty: 'oct',\n        ext: false,\n        kid: '81b20965-8332-43d9-a468-82160ad91ac8',\n        use: 'enc',\n        alg: 'A128KW',\n        k: 'GZy6sIZ6wl9NJOKB-jnmVQ',\n      },\n      alg: 'A128KW',\n      enc: 'A128GCM',\n      zip: 'DEF',\n    },\n    generated: {\n      plaintext_c:\n        'bY_BDcIwDEVX-QNU3QEOrIA4pqlDokYxchxVvbEDGzIJbioOSJwc-f___HPjBu8KVFpVtAplVE1-wZo0YjNZo3C7R5v72pV5f5X382VWjYQpqZKAyjziZOr2B7kQPSy6oZIXUnDYbVKN4jNXi2u0yB7t1qSHTjmMODf9QgvrDzfTIQXnyQRuUya4zIWG3vTOdir0v7BRHFYWq3k1k1A_gSDJqtcBF-GZxw8',\n      cek: 'hC-MpLZSuwWv8sexS6ydfw',\n      iv: 'p9pUq6XHY0jfEZIl',\n    },\n    encrypting_key: {},\n    encrypting_content: {\n      protected: {\n        alg: 'A128KW',\n        kid: '81b20965-8332-43d9-a468-82160ad91ac8',\n        enc: 'A128GCM',\n        zip: 'DEF',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIiwiemlwIjoiREVGIn0.5vUT2WOtQxKWcekM_IzVQwkGgzlFDwPi.p9pUq6XHY0jfEZIl.HbDtOsdai1oYziSx25KEeTxmwnh8L8jKMFNc1k3zmMI6VB8hry57tDZ61jXyezSPt0fdLVfe6Jf5y5-JaCap_JQBcb5opbmT60uWGml8blyiMQmOn9J--XhhlYg0m-BHaqfDO5iTOWxPxFMUedx7WCy8mxgDHj0aBMG6152PsM-w5E_o2B3jDbrYBKhpYA7qi3AyijnCJ7BP9rr3U8kxExCpG3mK420TjOw.VILuUwuIxaLVmh5X-T7kmA',\n      json: {\n        recipients: [\n          {\n            encrypted_key: '5vUT2WOtQxKWcekM_IzVQwkGgzlFDwPi',\n          },\n        ],\n        protected:\n          'eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIiwiemlwIjoiREVGIn0',\n        iv: 'p9pUq6XHY0jfEZIl',\n        ciphertext:\n          'HbDtOsdai1oYziSx25KEeTxmwnh8L8jKMFNc1k3zmMI6VB8hry57tDZ61jXyezSPt0fdLVfe6Jf5y5-JaCap_JQBcb5opbmT60uWGml8blyiMQmOn9J--XhhlYg0m-BHaqfDO5iTOWxPxFMUedx7WCy8mxgDHj0aBMG6152PsM-w5E_o2B3jDbrYBKhpYA7qi3AyijnCJ7BP9rr3U8kxExCpG3mK420TjOw',\n        tag: 'VILuUwuIxaLVmh5X-T7kmA',\n      },\n      json_flat: {\n        protected:\n          'eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIiwiemlwIjoiREVGIn0',\n        encrypted_key: '5vUT2WOtQxKWcekM_IzVQwkGgzlFDwPi',\n        iv: 'p9pUq6XHY0jfEZIl',\n        ciphertext:\n          'HbDtOsdai1oYziSx25KEeTxmwnh8L8jKMFNc1k3zmMI6VB8hry57tDZ61jXyezSPt0fdLVfe6Jf5y5-JaCap_JQBcb5opbmT60uWGml8blyiMQmOn9J--XhhlYg0m-BHaqfDO5iTOWxPxFMUedx7WCy8mxgDHj0aBMG6152PsM-w5E_o2B3jDbrYBKhpYA7qi3AyijnCJ7BP9rr3U8kxExCpG3mK420TjOw',\n        tag: 'VILuUwuIxaLVmh5X-T7kmA',\n      },\n    },\n  },\n  {\n    title:\n      'https://www.rfc-editor.org/rfc/rfc7520#section-5.10 - Including Additional Authenticated Data',\n    deterministic: true,\n    input: {\n      plaintext:\n        'You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.',\n      key: {\n        kty: 'oct',\n        ext: false,\n        kid: '81b20965-8332-43d9-a468-82160ad91ac8',\n        use: 'enc',\n        alg: 'A128KW',\n        k: 'GZy6sIZ6wl9NJOKB-jnmVQ',\n      },\n      alg: 'A128KW',\n      enc: 'A128GCM',\n      aad: '[\"vcard\",[[\"version\",{},\"text\",\"4.0\"],[\"fn\",{},\"text\",\"Meriadoc Brandybuck\"],[\"n\",{},\"text\",[\"Brandybuck\",\"Meriadoc\",\"Mr.\",\"\"]],[\"bday\",{},\"text\",\"TA 2982\"],[\"gender\",{},\"text\",\"M\"]]]',\n    },\n    generated: {\n      cek: '75m1ALsYv10pZTKPWrsqdg',\n      iv: 'veCx9ece2orS7c_N',\n      aad_b64u:\n        'WyJ2Y2FyZCIsW1sidmVyc2lvbiIse30sInRleHQiLCI0LjAiXSxbImZuIix7fSwidGV4dCIsIk1lcmlhZG9jIEJyYW5keWJ1Y2siXSxbIm4iLHt9LCJ0ZXh0IixbIkJyYW5keWJ1Y2siLCJNZXJpYWRvYyIsIk1yLiIsIiJdXSxbImJkYXkiLHt9LCJ0ZXh0IiwiVEEgMjk4MiJdLFsiZ2VuZGVyIix7fSwidGV4dCIsIk0iXV1d',\n    },\n    encrypting_key: {},\n    encrypting_content: {\n      protected: {\n        alg: 'A128KW',\n        kid: '81b20965-8332-43d9-a468-82160ad91ac8',\n        enc: 'A128GCM',\n      },\n    },\n    output: {\n      json: {\n        recipients: [\n          {\n            encrypted_key: '4YiiQ_ZzH76TaIkJmYfRFgOV9MIpnx4X',\n          },\n        ],\n        protected:\n          'eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIn0',\n        iv: 'veCx9ece2orS7c_N',\n        aad: 'WyJ2Y2FyZCIsW1sidmVyc2lvbiIse30sInRleHQiLCI0LjAiXSxbImZuIix7fSwidGV4dCIsIk1lcmlhZG9jIEJyYW5keWJ1Y2siXSxbIm4iLHt9LCJ0ZXh0IixbIkJyYW5keWJ1Y2siLCJNZXJpYWRvYyIsIk1yLiIsIiJdXSxbImJkYXkiLHt9LCJ0ZXh0IiwiVEEgMjk4MiJdLFsiZ2VuZGVyIix7fSwidGV4dCIsIk0iXV1d',\n        ciphertext:\n          'Z_3cbr0k3bVM6N3oSNmHz7Lyf3iPppGf3Pj17wNZqteJ0Ui8p74SchQP8xygM1oFRWCNzeIa6s6BcEtp8qEFiqTUEyiNkOWDNoF14T_4NFqF-p2Mx8zkbKxI7oPK8KNarFbyxIDvICNqBLba-v3uzXBdB89fzOI-Lv4PjOFAQGHrgv1rjXAmKbgkft9cB4WeyZw8MldbBhc-V_KWZslrsLNygon_JJWd_ek6LQn5NRehvApqf9ZrxB4aq3FXBxOxCys35PhCdaggy2kfUfl2OkwKnWUbgXVD1C6HxLIlqHhCwXDG59weHrRDQeHyMRoBljoV3X_bUTJDnKBFOod7nLz-cj48JMx3SnCZTpbQAkFV',\n        tag: 'vOaH_Rajnpy_3hOtqvZHRA',\n      },\n      json_flat: {\n        protected:\n          'eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIn0',\n        encrypted_key: '4YiiQ_ZzH76TaIkJmYfRFgOV9MIpnx4X',\n        aad: 'WyJ2Y2FyZCIsW1sidmVyc2lvbiIse30sInRleHQiLCI0LjAiXSxbImZuIix7fSwidGV4dCIsIk1lcmlhZG9jIEJyYW5keWJ1Y2siXSxbIm4iLHt9LCJ0ZXh0IixbIkJyYW5keWJ1Y2siLCJNZXJpYWRvYyIsIk1yLiIsIiJdXSxbImJkYXkiLHt9LCJ0ZXh0IiwiVEEgMjk4MiJdLFsiZ2VuZGVyIix7fSwidGV4dCIsIk0iXV1d',\n        iv: 'veCx9ece2orS7c_N',\n        ciphertext:\n          'Z_3cbr0k3bVM6N3oSNmHz7Lyf3iPppGf3Pj17wNZqteJ0Ui8p74SchQP8xygM1oFRWCNzeIa6s6BcEtp8qEFiqTUEyiNkOWDNoF14T_4NFqF-p2Mx8zkbKxI7oPK8KNarFbyxIDvICNqBLba-v3uzXBdB89fzOI-Lv4PjOFAQGHrgv1rjXAmKbgkft9cB4WeyZw8MldbBhc-V_KWZslrsLNygon_JJWd_ek6LQn5NRehvApqf9ZrxB4aq3FXBxOxCys35PhCdaggy2kfUfl2OkwKnWUbgXVD1C6HxLIlqHhCwXDG59weHrRDQeHyMRoBljoV3X_bUTJDnKBFOod7nLz-cj48JMx3SnCZTpbQAkFV',\n        tag: 'vOaH_Rajnpy_3hOtqvZHRA',\n      },\n    },\n  },\n  {\n    title:\n      'https://www.rfc-editor.org/rfc/rfc7520#section-5.11 - Protecting Specific Header Fields',\n    deterministic: true,\n    input: {\n      plaintext:\n        'You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.',\n      key: {\n        kty: 'oct',\n        ext: false,\n        kid: '81b20965-8332-43d9-a468-82160ad91ac8',\n        use: 'enc',\n        alg: 'A128KW',\n        k: 'GZy6sIZ6wl9NJOKB-jnmVQ',\n      },\n      alg: 'A128KW',\n      enc: 'A128GCM',\n    },\n    generated: {\n      cek: 'WDgEptBmQs9ouUvArz6x6g',\n      iv: 'WgEJsDS9bkoXQ3nR',\n    },\n    encrypting_key: {},\n    encrypting_content: {\n      protected: {\n        enc: 'A128GCM',\n      },\n      unprotected: {\n        alg: 'A128KW',\n        kid: '81b20965-8332-43d9-a468-82160ad91ac8',\n      },\n    },\n    output: {\n      json: {\n        recipients: [\n          {\n            encrypted_key: 'jJIcM9J-hbx3wnqhf5FlkEYos0sHsF0H',\n          },\n        ],\n        unprotected: {\n          alg: 'A128KW',\n          kid: '81b20965-8332-43d9-a468-82160ad91ac8',\n        },\n        protected: 'eyJlbmMiOiJBMTI4R0NNIn0',\n        iv: 'WgEJsDS9bkoXQ3nR',\n        ciphertext:\n          'lIbCyRmRJxnB2yLQOTqjCDKV3H30ossOw3uD9DPsqLL2DM3swKkjOwQyZtWsFLYMj5YeLht_StAn21tHmQJuuNt64T8D4t6C7kC9OCCJ1IHAolUv4MyOt80MoPb8fZYbNKqplzYJgIL58g8N2v46OgyG637d6uuKPwhAnTGm_zWhqc_srOvgiLkzyFXPq1hBAURbc3-8BqeRb48iR1-_5g5UjWVD3lgiLCN_P7AW8mIiFvUNXBPJK3nOWL4teUPS8yHLbWeL83olU4UAgL48x-8dDkH23JykibVSQju-f7e-1xreHWXzWLHs1NqBbre0dEwK3HX_xM0LjUz77Krppgegoutpf5qaKg3l-_xMINmf',\n        tag: 'fNYLqpUe84KD45lvDiaBAQ',\n      },\n      json_flat: {\n        protected: 'eyJlbmMiOiJBMTI4R0NNIn0',\n        unprotected: {\n          alg: 'A128KW',\n          kid: '81b20965-8332-43d9-a468-82160ad91ac8',\n        },\n        encrypted_key: 'jJIcM9J-hbx3wnqhf5FlkEYos0sHsF0H',\n        iv: 'WgEJsDS9bkoXQ3nR',\n        ciphertext:\n          'lIbCyRmRJxnB2yLQOTqjCDKV3H30ossOw3uD9DPsqLL2DM3swKkjOwQyZtWsFLYMj5YeLht_StAn21tHmQJuuNt64T8D4t6C7kC9OCCJ1IHAolUv4MyOt80MoPb8fZYbNKqplzYJgIL58g8N2v46OgyG637d6uuKPwhAnTGm_zWhqc_srOvgiLkzyFXPq1hBAURbc3-8BqeRb48iR1-_5g5UjWVD3lgiLCN_P7AW8mIiFvUNXBPJK3nOWL4teUPS8yHLbWeL83olU4UAgL48x-8dDkH23JykibVSQju-f7e-1xreHWXzWLHs1NqBbre0dEwK3HX_xM0LjUz77Krppgegoutpf5qaKg3l-_xMINmf',\n        tag: 'fNYLqpUe84KD45lvDiaBAQ',\n      },\n    },\n  },\n  {\n    title: 'https://www.rfc-editor.org/rfc/rfc7520#section-5.12 - Protecting Content Only',\n    deterministic: true,\n    input: {\n      plaintext:\n        'You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.',\n      key: {\n        kty: 'oct',\n        ext: false,\n        kid: '81b20965-8332-43d9-a468-82160ad91ac8',\n        use: 'enc',\n        alg: 'A128KW',\n        k: 'GZy6sIZ6wl9NJOKB-jnmVQ',\n      },\n      alg: 'A128KW',\n      enc: 'A128GCM',\n    },\n    generated: {\n      cek: 'KBooAFl30QPV3vkcZlXnzQ',\n      iv: 'YihBoVOGsR1l7jCD',\n    },\n    encrypting_key: {},\n    encrypting_content: {\n      unprotected: {\n        alg: 'A128KW',\n        kid: '81b20965-8332-43d9-a468-82160ad91ac8',\n        enc: 'A128GCM',\n      },\n    },\n    output: {\n      json: {\n        recipients: [\n          {\n            encrypted_key: '244YHfO_W7RMpQW81UjQrZcq5LSyqiPv',\n          },\n        ],\n        unprotected: {\n          alg: 'A128KW',\n          kid: '81b20965-8332-43d9-a468-82160ad91ac8',\n          enc: 'A128GCM',\n        },\n        iv: 'YihBoVOGsR1l7jCD',\n        ciphertext:\n          'qtPIMMaOBRgASL10dNQhOa7Gqrk7Eal1vwht7R4TT1uq-arsVCPaIeFwQfzrSS6oEUWbBtxEasE0vC6r7sphyVziMCVJEuRJyoAHFSP3eqQPb4Ic1SDSqyXjw_L3svybhHYUGyQuTmUQEDjgjJfBOifwHIsDsRPeBz1NomqeifVPq5GTCWFo5k_MNIQURR2Wj0AHC2k7JZfu2iWjUHLF8ExFZLZ4nlmsvJu_mvifMYiikfNfsZAudISOa6O73yPZtL04k_1FI7WDfrb2w7OqKLWDXzlpcxohPVOLQwpA3mFNRKdY-bQz4Z4KX9lfz1cne31N4-8BKmojpw-OdQjKdLOGkC445Fb_K1tlDQXw2sBF',\n        tag: 'e2m0Vm7JvjK2VpCKXS-kyg',\n      },\n      json_flat: {\n        unprotected: {\n          alg: 'A128KW',\n          kid: '81b20965-8332-43d9-a468-82160ad91ac8',\n          enc: 'A128GCM',\n        },\n        encrypted_key: '244YHfO_W7RMpQW81UjQrZcq5LSyqiPv',\n        iv: 'YihBoVOGsR1l7jCD',\n        ciphertext:\n          'qtPIMMaOBRgASL10dNQhOa7Gqrk7Eal1vwht7R4TT1uq-arsVCPaIeFwQfzrSS6oEUWbBtxEasE0vC6r7sphyVziMCVJEuRJyoAHFSP3eqQPb4Ic1SDSqyXjw_L3svybhHYUGyQuTmUQEDjgjJfBOifwHIsDsRPeBz1NomqeifVPq5GTCWFo5k_MNIQURR2Wj0AHC2k7JZfu2iWjUHLF8ExFZLZ4nlmsvJu_mvifMYiikfNfsZAudISOa6O73yPZtL04k_1FI7WDfrb2w7OqKLWDXzlpcxohPVOLQwpA3mFNRKdY-bQz4Z4KX9lfz1cne31N4-8BKmojpw-OdQjKdLOGkC445Fb_K1tlDQXw2sBF',\n        tag: 'e2m0Vm7JvjK2VpCKXS-kyg',\n      },\n    },\n  },\n]\n"
  },
  {
    "path": "cookbook/jws.mjs",
    "content": "export default [\n  {\n    title: 'https://www.rfc-editor.org/rfc/rfc7520#section-4.1 - RSA v1.5 Signature',\n    deterministic: true,\n    input: {\n      payload:\n        \"It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there’s no knowing where you might be swept off to.\",\n      key: {\n        kty: 'RSA',\n        ext: false,\n        kid: 'bilbo.baggins@hobbiton.example',\n        use: 'sig',\n        n: 'n4EPtAOCc9AlkeQHPzHStgAbgs7bTZLwUBZdR8_KuKPEHLd4rHVTeT-O-XV2jRojdNhxJWTDvNd7nqQ0VEiZQHz_AJmSCpMaJMRBSFKrKb2wqVwGU_NsYOYL-QtiWN2lbzcEe6XC0dApr5ydQLrHqkHHig3RBordaZ6Aj-oBHqFEHYpPe7Tpe-OfVfHd1E6cS6M1FZcD1NNLYD5lFHpPI9bTwJlsde3uhGqC0ZCuEHg8lhzwOHrtIQbS0FVbb9k3-tVTU4fg_3L_vniUFAKwuCLqKnS2BYwdq_mzSnbLY7h_qixoR7jig3__kRhuaxwUkRz5iaiQkqgc5gHdrNP5zw',\n        e: 'AQAB',\n        d: 'bWUC9B-EFRIo8kpGfh0ZuyGPvMNKvYWNtB_ikiH9k20eT-O1q_I78eiZkpXxXQ0UTEs2LsNRS-8uJbvQ-A1irkwMSMkK1J3XTGgdrhCku9gRldY7sNA_AKZGh-Q661_42rINLRCe8W-nZ34ui_qOfkLnK9QWDDqpaIsA-bMwWWSDFu2MUBYwkHTMEzLYGqOe04noqeq1hExBTHBOBdkMXiuFhUq1BU6l-DqEiWxqg82sXt2h-LMnT3046AOYJoRioz75tSUQfGCshWTBnP5uDjd18kKhyv07lhfSJdrPdM5Plyl21hsFf4L_mHCuoFau7gdsPfHPxxjVOcOpBrQzwQ',\n        p: '3Slxg_DwTXJcb6095RoXygQCAZ5RnAvZlno1yhHtnUex_fp7AZ_9nRaO7HX_-SFfGQeutao2TDjDAWU4Vupk8rw9JR0AzZ0N2fvuIAmr_WCsmGpeNqQnev1T7IyEsnh8UMt-n5CafhkikzhEsrmndH6LxOrvRJlsPp6Zv8bUq0k',\n        q: 'uKE2dh-cTf6ERF4k4e_jy78GfPYUIaUyoSSJuBzp3Cubk3OCqs6grT8bR_cu0Dm1MZwWmtdqDyI95HrUeq3MP15vMMON8lHTeZu2lmKvwqW7anV5UzhM1iZ7z4yMkuUwFWoBvyY898EXvRD-hdqRxHlSqAZ192zB3pVFJ0s7pFc',\n        dp: 'B8PVvXkvJrj2L-GYQ7v3y9r6Kw5g9SahXBwsWUzp19TVlgI-YV85q1NIb1rxQtD-IsXXR3-TanevuRPRt5OBOdiMGQp8pbt26gljYfKU_E9xn-RULHz0-ed9E9gXLKD4VGngpz-PfQ_q29pk5xWHoJp009Qf1HvChixRX59ehik',\n        dq: 'CLDmDGduhylc9o7r84rEUVn7pzQ6PF83Y-iBZx5NT-TpnOZKF1pErAMVeKzFEl41DlHHqqBLSM0W1sOFbwTxYWZDm6sI6og5iTbwQGIC3gnJKbi_7k_vJgGHwHxgPaX2PnvP-zyEkDERuf-ry4c_Z11Cq9AqC2yeL6kdKT1cYF8',\n        qi: '3PiqvXQN0zwMeE-sBvZgi289XP9XCQF3VWqPzMKnIgQp7_Tugo6-NZBKCQsMf3HaEGBjTVJs_jcK8-TRXvaKe-7ZMaQj8VfBdYkssbu0NKDDhjJ-GtiseaDVWt7dcH0cfwxgFUHpQh7FoCrjFJ6h6ZEpMF6xmujs4qMpPz8aaI4',\n      },\n      alg: 'RS256',\n    },\n    signing: {\n      protected: {\n        alg: 'RS256',\n        kid: 'bilbo.baggins@hobbiton.example',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJSUzI1NiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4.MRjdkly7_-oTPTS3AXP41iQIGKa80A0ZmTuV5MEaHoxnW2e5CZ5NlKtainoFmKZopdHM1O2U4mwzJdQx996ivp83xuglII7PNDi84wnB-BDkoBwA78185hX-Es4JIwmDLJK3lfWRa-XtL0RnltuYv746iYTh_qHRD68BNt1uSNCrUCTJDt5aAE6x8wW1Kt9eRo4QPocSadnHXFxnt8Is9UzpERV0ePPQdLuW3IS_de3xyIrDaLGdjluPxUAhb6L2aXic1U12podGU0KLUQSE_oI-ZnmKJ3F4uOZDnd6QZWJushZ41Axf_fcIe8u9ipH84ogoree7vjbU5y18kDquDg',\n      json: {\n        payload:\n          'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4',\n        signatures: [\n          {\n            protected: 'eyJhbGciOiJSUzI1NiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9',\n            signature:\n              'MRjdkly7_-oTPTS3AXP41iQIGKa80A0ZmTuV5MEaHoxnW2e5CZ5NlKtainoFmKZopdHM1O2U4mwzJdQx996ivp83xuglII7PNDi84wnB-BDkoBwA78185hX-Es4JIwmDLJK3lfWRa-XtL0RnltuYv746iYTh_qHRD68BNt1uSNCrUCTJDt5aAE6x8wW1Kt9eRo4QPocSadnHXFxnt8Is9UzpERV0ePPQdLuW3IS_de3xyIrDaLGdjluPxUAhb6L2aXic1U12podGU0KLUQSE_oI-ZnmKJ3F4uOZDnd6QZWJushZ41Axf_fcIe8u9ipH84ogoree7vjbU5y18kDquDg',\n          },\n        ],\n      },\n      json_flat: {\n        payload:\n          'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4',\n        protected: 'eyJhbGciOiJSUzI1NiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9',\n        signature:\n          'MRjdkly7_-oTPTS3AXP41iQIGKa80A0ZmTuV5MEaHoxnW2e5CZ5NlKtainoFmKZopdHM1O2U4mwzJdQx996ivp83xuglII7PNDi84wnB-BDkoBwA78185hX-Es4JIwmDLJK3lfWRa-XtL0RnltuYv746iYTh_qHRD68BNt1uSNCrUCTJDt5aAE6x8wW1Kt9eRo4QPocSadnHXFxnt8Is9UzpERV0ePPQdLuW3IS_de3xyIrDaLGdjluPxUAhb6L2aXic1U12podGU0KLUQSE_oI-ZnmKJ3F4uOZDnd6QZWJushZ41Axf_fcIe8u9ipH84ogoree7vjbU5y18kDquDg',\n      },\n    },\n  },\n  {\n    title: 'https://www.rfc-editor.org/rfc/rfc8037#appendix-A.4 - Ed25519 Signing',\n    deterministic: false, // https://github.com/WICG/webcrypto-secure-curves/issues/28\n    input: {\n      payload: 'Example of Ed25519 signing',\n      key: {\n        kty: 'OKP',\n        ext: false,\n        crv: 'Ed25519',\n        d: 'nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A',\n        x: '11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo',\n      },\n      alg: 'EdDSA',\n    },\n    signing: {\n      protected: {\n        alg: 'EdDSA',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJFZERTQSJ9.RXhhbXBsZSBvZiBFZDI1NTE5IHNpZ25pbmc.hgyY0il_MGCjP0JzlnLWG1PPOt7-09PGcvMg3AIbQR6dWbhijcNR4ki4iylGjg5BhVsPt9g7sVvpAr_MuM0KAg',\n      json: {\n        payload: 'RXhhbXBsZSBvZiBFZDI1NTE5IHNpZ25pbmc',\n        signatures: [\n          {\n            protected: 'eyJhbGciOiJFZERTQSJ9',\n            signature:\n              'hgyY0il_MGCjP0JzlnLWG1PPOt7-09PGcvMg3AIbQR6dWbhijcNR4ki4iylGjg5BhVsPt9g7sVvpAr_MuM0KAg',\n          },\n        ],\n      },\n      json_flat: {\n        payload: 'RXhhbXBsZSBvZiBFZDI1NTE5IHNpZ25pbmc',\n        protected: 'eyJhbGciOiJFZERTQSJ9',\n        signature:\n          'hgyY0il_MGCjP0JzlnLWG1PPOt7-09PGcvMg3AIbQR6dWbhijcNR4ki4iylGjg5BhVsPt9g7sVvpAr_MuM0KAg',\n      },\n    },\n  },\n  {\n    title: 'https://www.rfc-editor.org/rfc/rfc7520#section-4.2 - RSA-PSS Signature',\n    input: {\n      payload:\n        \"It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there’s no knowing where you might be swept off to.\",\n      key: {\n        kty: 'RSA',\n        ext: false,\n        kid: 'bilbo.baggins@hobbiton.example',\n        use: 'sig',\n        n: 'n4EPtAOCc9AlkeQHPzHStgAbgs7bTZLwUBZdR8_KuKPEHLd4rHVTeT-O-XV2jRojdNhxJWTDvNd7nqQ0VEiZQHz_AJmSCpMaJMRBSFKrKb2wqVwGU_NsYOYL-QtiWN2lbzcEe6XC0dApr5ydQLrHqkHHig3RBordaZ6Aj-oBHqFEHYpPe7Tpe-OfVfHd1E6cS6M1FZcD1NNLYD5lFHpPI9bTwJlsde3uhGqC0ZCuEHg8lhzwOHrtIQbS0FVbb9k3-tVTU4fg_3L_vniUFAKwuCLqKnS2BYwdq_mzSnbLY7h_qixoR7jig3__kRhuaxwUkRz5iaiQkqgc5gHdrNP5zw',\n        e: 'AQAB',\n        d: 'bWUC9B-EFRIo8kpGfh0ZuyGPvMNKvYWNtB_ikiH9k20eT-O1q_I78eiZkpXxXQ0UTEs2LsNRS-8uJbvQ-A1irkwMSMkK1J3XTGgdrhCku9gRldY7sNA_AKZGh-Q661_42rINLRCe8W-nZ34ui_qOfkLnK9QWDDqpaIsA-bMwWWSDFu2MUBYwkHTMEzLYGqOe04noqeq1hExBTHBOBdkMXiuFhUq1BU6l-DqEiWxqg82sXt2h-LMnT3046AOYJoRioz75tSUQfGCshWTBnP5uDjd18kKhyv07lhfSJdrPdM5Plyl21hsFf4L_mHCuoFau7gdsPfHPxxjVOcOpBrQzwQ',\n        p: '3Slxg_DwTXJcb6095RoXygQCAZ5RnAvZlno1yhHtnUex_fp7AZ_9nRaO7HX_-SFfGQeutao2TDjDAWU4Vupk8rw9JR0AzZ0N2fvuIAmr_WCsmGpeNqQnev1T7IyEsnh8UMt-n5CafhkikzhEsrmndH6LxOrvRJlsPp6Zv8bUq0k',\n        q: 'uKE2dh-cTf6ERF4k4e_jy78GfPYUIaUyoSSJuBzp3Cubk3OCqs6grT8bR_cu0Dm1MZwWmtdqDyI95HrUeq3MP15vMMON8lHTeZu2lmKvwqW7anV5UzhM1iZ7z4yMkuUwFWoBvyY898EXvRD-hdqRxHlSqAZ192zB3pVFJ0s7pFc',\n        dp: 'B8PVvXkvJrj2L-GYQ7v3y9r6Kw5g9SahXBwsWUzp19TVlgI-YV85q1NIb1rxQtD-IsXXR3-TanevuRPRt5OBOdiMGQp8pbt26gljYfKU_E9xn-RULHz0-ed9E9gXLKD4VGngpz-PfQ_q29pk5xWHoJp009Qf1HvChixRX59ehik',\n        dq: 'CLDmDGduhylc9o7r84rEUVn7pzQ6PF83Y-iBZx5NT-TpnOZKF1pErAMVeKzFEl41DlHHqqBLSM0W1sOFbwTxYWZDm6sI6og5iTbwQGIC3gnJKbi_7k_vJgGHwHxgPaX2PnvP-zyEkDERuf-ry4c_Z11Cq9AqC2yeL6kdKT1cYF8',\n        qi: '3PiqvXQN0zwMeE-sBvZgi289XP9XCQF3VWqPzMKnIgQp7_Tugo6-NZBKCQsMf3HaEGBjTVJs_jcK8-TRXvaKe-7ZMaQj8VfBdYkssbu0NKDDhjJ-GtiseaDVWt7dcH0cfwxgFUHpQh7FoCrjFJ6h6ZEpMF6xmujs4qMpPz8aaI4',\n      },\n      alg: 'PS384',\n    },\n    signing: {\n      protected: {\n        alg: 'PS384',\n        kid: 'bilbo.baggins@hobbiton.example',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJQUzM4NCIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4.cu22eBqkYDKgIlTpzDXGvaFfz6WGoz7fUDcfT0kkOy42miAh2qyBzk1xEsnk2IpN6-tPid6VrklHkqsGqDqHCdP6O8TTB5dDDItllVo6_1OLPpcbUrhiUSMxbbXUvdvWXzg-UD8biiReQFlfz28zGWVsdiNAUf8ZnyPEgVFn442ZdNqiVJRmBqrYRXe8P_ijQ7p8Vdz0TTrxUeT3lm8d9shnr2lfJT8ImUjvAA2Xez2Mlp8cBE5awDzT0qI0n6uiP1aCN_2_jLAeQTlqRHtfa64QQSUmFAAjVKPbByi7xho0uTOcbH510a6GYmJUAfmWjwZ6oD4ifKo8DYM-X72Eaw',\n      json: {\n        payload:\n          'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4',\n        signatures: [\n          {\n            protected: 'eyJhbGciOiJQUzM4NCIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9',\n            signature:\n              'cu22eBqkYDKgIlTpzDXGvaFfz6WGoz7fUDcfT0kkOy42miAh2qyBzk1xEsnk2IpN6-tPid6VrklHkqsGqDqHCdP6O8TTB5dDDItllVo6_1OLPpcbUrhiUSMxbbXUvdvWXzg-UD8biiReQFlfz28zGWVsdiNAUf8ZnyPEgVFn442ZdNqiVJRmBqrYRXe8P_ijQ7p8Vdz0TTrxUeT3lm8d9shnr2lfJT8ImUjvAA2Xez2Mlp8cBE5awDzT0qI0n6uiP1aCN_2_jLAeQTlqRHtfa64QQSUmFAAjVKPbByi7xho0uTOcbH510a6GYmJUAfmWjwZ6oD4ifKo8DYM-X72Eaw',\n          },\n        ],\n      },\n      json_flat: {\n        payload:\n          'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4',\n        protected: 'eyJhbGciOiJQUzM4NCIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9',\n        signature:\n          'cu22eBqkYDKgIlTpzDXGvaFfz6WGoz7fUDcfT0kkOy42miAh2qyBzk1xEsnk2IpN6-tPid6VrklHkqsGqDqHCdP6O8TTB5dDDItllVo6_1OLPpcbUrhiUSMxbbXUvdvWXzg-UD8biiReQFlfz28zGWVsdiNAUf8ZnyPEgVFn442ZdNqiVJRmBqrYRXe8P_ijQ7p8Vdz0TTrxUeT3lm8d9shnr2lfJT8ImUjvAA2Xez2Mlp8cBE5awDzT0qI0n6uiP1aCN_2_jLAeQTlqRHtfa64QQSUmFAAjVKPbByi7xho0uTOcbH510a6GYmJUAfmWjwZ6oD4ifKo8DYM-X72Eaw',\n      },\n    },\n  },\n  {\n    title: 'https://www.rfc-editor.org/rfc/rfc7520#section-4.3 - ECDSA Signature',\n    input: {\n      payload:\n        \"It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there’s no knowing where you might be swept off to.\",\n      key: {\n        kty: 'EC',\n        ext: false,\n        kid: 'bilbo.baggins@hobbiton.example',\n        use: 'sig',\n        crv: 'P-521',\n        x: 'AHKZLLOsCOzz5cY97ewNUajB957y-C-U88c3v13nmGZx6sYl_oJXu9A5RkTKqjqvjyekWF-7ytDyRXYgCF5cj0Kt',\n        y: 'AdymlHvOiLxXkEhayXQnNCvDX4h9htZaCJN34kfmC6pV5OhQHiraVySsUdaQkAgDPrwQrJmbnX9cwlGfP-HqHZR1',\n        d: 'AAhRON2r9cqXX1hg-RoI6R1tX5p2rUAYdmpHZoC1XNM56KtscrX6zbKipQrCW9CGZH3T4ubpnoTKLDYJ_fF3_rJt',\n      },\n      alg: 'ES512',\n    },\n    signing: {\n      protected: {\n        alg: 'ES512',\n        kid: 'bilbo.baggins@hobbiton.example',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJFUzUxMiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4.AE_R_YZCChjn4791jSQCrdPZCNYqHXCTZH0-JZGYNlaAjP2kqaluUIIUnC9qvbu9Plon7KRTzoNEuT4Va2cmL1eJAQy3mtPBu_u_sDDyYjnAMDxXPn7XrT0lw-kvAD890jl8e2puQens_IEKBpHABlsbEPX6sFY8OcGDqoRuBomu9xQ2',\n      json: {\n        payload:\n          'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4',\n        signatures: [\n          {\n            protected: 'eyJhbGciOiJFUzUxMiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9',\n            signature:\n              'AE_R_YZCChjn4791jSQCrdPZCNYqHXCTZH0-JZGYNlaAjP2kqaluUIIUnC9qvbu9Plon7KRTzoNEuT4Va2cmL1eJAQy3mtPBu_u_sDDyYjnAMDxXPn7XrT0lw-kvAD890jl8e2puQens_IEKBpHABlsbEPX6sFY8OcGDqoRuBomu9xQ2',\n          },\n        ],\n      },\n      json_flat: {\n        payload:\n          'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4',\n        protected: 'eyJhbGciOiJFUzUxMiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9',\n        signature:\n          'AE_R_YZCChjn4791jSQCrdPZCNYqHXCTZH0-JZGYNlaAjP2kqaluUIIUnC9qvbu9Plon7KRTzoNEuT4Va2cmL1eJAQy3mtPBu_u_sDDyYjnAMDxXPn7XrT0lw-kvAD890jl8e2puQens_IEKBpHABlsbEPX6sFY8OcGDqoRuBomu9xQ2',\n      },\n    },\n  },\n  {\n    title: 'https://www.rfc-editor.org/rfc/rfc7520#section-4.4 - HMAC-SHA2 Integrity Protection',\n    deterministic: true,\n    input: {\n      payload:\n        \"It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there’s no knowing where you might be swept off to.\",\n      key: {\n        kty: 'oct',\n        ext: false,\n        kid: '018c0ae5-4d9b-471b-bfd6-eef314bc7037',\n        use: 'sig',\n        alg: 'HS256',\n        k: 'hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg',\n      },\n      alg: 'HS256',\n    },\n    signing: {\n      protected: {\n        alg: 'HS256',\n        kid: '018c0ae5-4d9b-471b-bfd6-eef314bc7037',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4.s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0',\n      json: {\n        payload:\n          'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4',\n        signatures: [\n          {\n            protected:\n              'eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9',\n            signature: 's0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0',\n          },\n        ],\n      },\n      json_flat: {\n        payload:\n          'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4',\n        protected:\n          'eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9',\n        signature: 's0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0',\n      },\n    },\n  },\n  {\n    title: 'https://www.rfc-editor.org/rfc/rfc7520#section-4.6 - Protecting Specific Header Fields',\n    deterministic: true,\n    input: {\n      payload:\n        \"It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there’s no knowing where you might be swept off to.\",\n      key: {\n        kty: 'oct',\n        ext: false,\n        kid: '018c0ae5-4d9b-471b-bfd6-eef314bc7037',\n        use: 'sig',\n        alg: 'HS256',\n        k: 'hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg',\n      },\n      alg: 'HS256',\n    },\n    signing: {\n      protected: {\n        alg: 'HS256',\n      },\n      unprotected: {\n        kid: '018c0ae5-4d9b-471b-bfd6-eef314bc7037',\n      },\n    },\n    output: {\n      json: {\n        payload:\n          'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4',\n        signatures: [\n          {\n            protected: 'eyJhbGciOiJIUzI1NiJ9',\n            header: {\n              kid: '018c0ae5-4d9b-471b-bfd6-eef314bc7037',\n            },\n            signature: 'bWUSVaxorn7bEF1djytBd0kHv70Ly5pvbomzMWSOr20',\n          },\n        ],\n      },\n      json_flat: {\n        payload:\n          'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4',\n        protected: 'eyJhbGciOiJIUzI1NiJ9',\n        header: {\n          kid: '018c0ae5-4d9b-471b-bfd6-eef314bc7037',\n        },\n        signature: 'bWUSVaxorn7bEF1djytBd0kHv70Ly5pvbomzMWSOr20',\n      },\n    },\n  },\n  {\n    title: 'https://www.rfc-editor.org/rfc/rfc7520#section-4.7 - Protecting Content Only',\n    deterministic: true,\n    input: {\n      payload:\n        \"It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there’s no knowing where you might be swept off to.\",\n      key: {\n        kty: 'oct',\n        ext: false,\n        kid: '018c0ae5-4d9b-471b-bfd6-eef314bc7037',\n        use: 'sig',\n        alg: 'HS256',\n        k: 'hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg',\n      },\n      alg: 'HS256',\n    },\n    signing: {\n      unprotected: {\n        alg: 'HS256',\n        kid: '018c0ae5-4d9b-471b-bfd6-eef314bc7037',\n      },\n    },\n    output: {\n      json: {\n        payload:\n          'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4',\n        signatures: [\n          {\n            header: {\n              alg: 'HS256',\n              kid: '018c0ae5-4d9b-471b-bfd6-eef314bc7037',\n            },\n            signature: 'xuLifqLGiblpv9zBpuZczWhNj1gARaLV3UxvxhJxZuk',\n          },\n        ],\n      },\n      json_flat: {\n        payload:\n          'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4',\n        header: {\n          alg: 'HS256',\n          kid: '018c0ae5-4d9b-471b-bfd6-eef314bc7037',\n        },\n        signature: 'xuLifqLGiblpv9zBpuZczWhNj1gARaLV3UxvxhJxZuk',\n      },\n    },\n  },\n  {\n    title: 'https://www.rfc-editor.org/rfc/rfc7797#section-4.1 - { \"b64\": false } JSON only',\n    deterministic: true,\n    input: {\n      payload: '$.02',\n      key: {\n        kty: 'oct',\n        ext: false,\n        alg: 'HS256',\n        k: 'AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow',\n      },\n      alg: 'HS256',\n    },\n    signing: {\n      protected: {\n        alg: 'HS256',\n        b64: false,\n        crit: ['b64'],\n      },\n    },\n    output: {\n      json: {\n        payload: '$.02',\n        signatures: [\n          {\n            protected: 'eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19',\n            signature: 'A5dxf2s96_n5FLueVuW1Z_vh161FwXZC4YLPff6dmDY',\n          },\n        ],\n      },\n      json_flat: {\n        payload: '$.02',\n        protected: 'eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19',\n        signature: 'A5dxf2s96_n5FLueVuW1Z_vh161FwXZC4YLPff6dmDY',\n      },\n    },\n  },\n  {\n    title: 'ietf-cose-dilithium - ML-DSA-44',\n    deterministic: false,\n    input: {\n      payload: 'It’s a dangerous business, Frodo, going out your door.',\n      key: {\n        kty: 'AKP',\n        alg: 'ML-DSA-44',\n        pub: 'unH59k4RuutY-pxvu24U5h8YZD2rSVtHU5qRZsoBmBMcRPgmu9VuNOVdteXi1zNIXjnqJg_GAAxepLqA00Vc3lO0bzRIKu39VFD8Lhuk8l0V-cFEJC-zm7UihxiQMMUEmOFxe3x1ixkKZ0jqmqP3rKryx8tSbtcXyfea64QhT6XNje2SoMP6FViBDxLHBQo2dwjRls0k5a-XSQSu2OTOiHLoaWsLe8pQ5FLNfTDqmkrawDEdZyxr3oSWJAsHQxRjcIiVzZuvwxYy1zl2STiP2vy_fTBaPemkleynQzqPg7oPCyXEE8bjnJbrfWkbNNN8438e6tHPIX4l7zTuzz98YPhLjt_d6EBdT4MldsYe-Y4KLyjaGHcAlTkk9oa5RhRwW89T0z_t1DSO3dvfKLUGXh8gd1BD6Fz5MfgpF5NjoafnQEqDjsAAhrCXY4b-Y3yYJEdX4_dp3dRGdHG_rWcPmgX4JG7lCnser4f8QGnDriqiAzJYEXeS8LzUngg_0bx0lqv_KcyU5IaLISFO0xZSU5mmEPvdSoDnyAcV8pV44qhLtAvd29n0ehG259oRihtljTWeiu9V60a1N2tbZVl5mEqSK-6_xZvNYA1TCdzNctvweH24unV7U3wer9XA9Q6kvJWDVJ4oKaQsKMrCSMlteBJMRxWbGK7ddUq6F7GdQw-3j2M-qdJvVKm9UPjY9rc1lPgol25-oJxTu7nxGlbJUH-4m5pevAN6NyZ6lfhbjWTKlxkrEKZvQXs_Yf6cpXEwpI_ZJeriq1UC1XHIpRkDwdOY9MH3an4RdDl2r9vGl_IwlKPNdh_5aF3jLgn7PCit1FNJAwC8fIncAXgAlgcXIpRXdfJk4bBiO89GGccSyDh2EgXYdpG3XvNgGWy7npuSoNTE7WIyblAk13UQuO4sdCbMIuriCdyfE73mvwj15xgb07RZRQtFGlFTmnFcIdZ90zDrWXDbANntv7KCKwNvoTuv64bY3HiGbj-NQ-U9eMylWVpvr4hrXcES8c9K3PqHWADZC0iIOvlzFv4VBoc_wVflcOrL_SIoaNFCNBAZZq-2v5lAgpJTqVOtqJ_HVraoSfcKy5g45p-qULunXj6Jwq21fobQiKubBKKOZwcJFyJD7F4ACKXOrz-HIvSHMCWW_9dVrRuCpJw0s0aVFbRqopDNhu446nqb4_EDYQM1tTHMozPd_jKxRRD0sH75X8ZoToxFSpLBDbtdWcenxj-zBf6IGWfZnmaetjKEBYJWC7QDQx1A91pJVJCEgieCkoIfTqkeQuePpIyu48g2FG3P1zjRF-kumhUTfSjo5qS0YiZQy0E1BMs6M11EvuxXRsHClLHoy5nLYI2Sj4zjVjYyxSHyPRPGGo9hwB34yWxzYNtPPGiqXS_dNCpi_zRZwRY4lCGrQ-hYTEWIK1Dm5OlttvC4_eiQ1dv63NiGkLRJ5kJA3bICN0fzCDY-MBqnd1cWn8YVBijVkgtaoascjL9EywDgJdeHnXK0eeOvUxHHhXJVkNqcibn8O4RQdpVU60TSA-uiu675ytIjcBHC6kTv8A8pmkj_4oypPd-F92YIJC741swkYQoeIHj8rE-ThcMUkF7KqC5VORbZTRp8HsZSqgiJcIPaouuxd1-8Rxrid3fXkE6p8bkrysPYoxWEJgh7ZFsRCPDWX-yTeJwFN0PKFP1j0F6YtlLfK5wv-c4F8ZQHA_-yc_gODicy7KmWDZgbTP07e7gEWzw4MFRrndjbDQ',\n        priv: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\n      },\n      alg: 'ML-DSA-44',\n    },\n    signing: {\n      protected: {\n        alg: 'ML-DSA-44',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJNTC1EU0EtNDQiLCJraWQiOiJUNHhsNzBTN01UNlplcTZyOVY5ZlBKR1ZuNzZ3Zm5YSjIxLWd5bzBHdTZvIn0.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4.knI1Q_9CIzLH5Xy94Kkc7WVKqZcAgtJ3mNf0GUj1uLA6YXAWFJfXkh-zQxUtEl3UIC7zPCiUwKTDR6ZsuUmFj8Ctb_6aH64hElN7weS_1m5okCy8GqHNL2lsfclCH3Y2f4QNP-DLVS1XsuboDA7Dw3ir2IdYKIfWJyIU7ROHgd24nuun1zJbxcLJC2EKt2M8R0wZudcIE9nm5oPzYXq0z-hPsKoXp9leVYkqgMmO9Lo8SP_1YYIEth3B8v-GuP249KDTFRKPjISmK4aPCknjtjihHsQVv2XePXxKExatHl4qhsiiW-y-EJXa1Kfw4WYpLA7B4_5Ids--cIJmIx7f6xxAWKh5qoBWq1QIOaaFuzsAraRW3NOEuzThew1En85gI3GcRTZGp-VDGyxHm0Al04cyWo2bxAVOF0fbDc265iP2mCNw6Qg10jIJeAhGB4OAMYcBUWJAG0l1MN1U_koEmGh5dXKnQTRl461ea_Cq3DLkcA2Dj2woWUFyDTmQ8oO_yheASfJacyRm7_suj88z5XFNo8F53P8OxTG9xUPlrwvH-TAq7AH3NU4SNXApyVKTU3zhx1tJ34nlTILcTujXVJVo_f0DZfUxr6JSCYqvy4z1Kl0wDQzd55aopyFtQxvOPhcCHbAN34g2Ug750Jm835fl7NOxcqoMbuTcgH68kr37M-Pdh2K9WazXUJgCupgdIWW8WjfOjmTiF59CrVtfVtK2qDzF40OENCfqtNPQlZe5cN5p0P8arj4USB8HCPh7NdqQBAeWrw0wsYhdiM39lrSkA8mLRYMhZnqKGCTPCrHXDdEjRKYRNaqIUT44laYl5c27K0v-ozjKPu6tzEhkYSC4XZ3LehEFtmAzOE0mHbhKMgXqjoPJjOrGIPibX3jwK8_Q5RmMOXtXo8R3vXfBaUdQoLeeyywNYE0nIcsl4z5a8_utwEFiVf0VK2pdviyiOPVSi3zOMAmqz6gFhVy8aMMQOWZAEAuTyDw7ZWG6diwptmrgSXZotW63I19S2ZH7keCXRIq_pFLuYhOuG6dD4MkouILRdC9bXZMLrNDq7COpUOO86aQVlYd0pR935WpUw-V6obSRnHlRFZSmUSIB7h1Q0ImciRzojN93Xhw7qpzGzdzDEO3OOTayXaSG_0YHQyy-eH4hBbmgt_LBx120g1eY4XHeHFRfTfetHkL5ZZusX1jQ_nk9ez4XBG_6hRtTNSuVBsYlH8-KUuR5-qTP8dkvRf8Wk2hHoUr2sz5YO_xDFCMMTrt8ahiMyfjo5ih5Fwo3riFbFUGKibniTLXspFd4spcNK_WchlZLRgkPK4jh6Z_X8JJkHxvQhpyouHQFyGxgBrl24x-_EB1zbWMhJthmm8DiKt-nzKaJz8Cju1-HwCpg76CRqRsEz2hyKEpbb4M5KQSj3AsENCroVmQ5QIv3K2XNRkve4vjBmP6sV2b6GSY_UeRvPElA7SUgBGTKbn-c0aYhBuB8plPhRTBa55_cFqAmNmavF1-fdMktJuIaH2f-K0zZCzbHw54998T7kIWgyMsyGCAvynEB_khOqwT7tCjg5HQ8SIjdnRYW0kjZfjt5LJbGA-PnRo8gPVQVGeYDP2vsSXhNJY94AitKCY1srcSsuYDrhNBKrnoJ1uEsMPVHsgFw_ZHMyAEaVQughSNW4fm8q6_1Nv4zLutDITzmAL6a6i6-WS6QRIs_4VUtwr5cXXIFDDeHVWeGcNivQ6W9urEUP4crguiq7z_DTiYaGfUksub-T7mw0zU8ZoOSd5pUTpJLv-IYIUAl6CscHvunnRLEKqpW1Sa1dcFZs5VP4AfR3mg7wX4Vlq1AHnpFxE2L1LZiKoTc9jDEOvTDkxr86gMkwMm6RdyPF_q48AVJ1br8Qp88-4B84X52zZ5cw-IJYe-HiVJ29LpeYm340_rWivpy-UB5i9TKlMrxf94y1okzZTPbP3_v1_XX0nE7RTLz98EA96euJ7l3EpbEqks7mh6i1FJNnvvlM_u29sYobJ6PUT-i1VlQnF_JBARKEz74pBXm1l5Y5Lo15rsIlaQHinUBCO8fHCHI59LAfKusN4JmodDqLYwkWijEL_sfrC6LtrbXqpM1pw09zSrs_tS1RQ-LnWHuPrU5KLCzv53JKrh8lU_cdBowe_F-Ib_Ui4bQ2FME-0mnyG0XijHUsrGMZ9dfowvIkr83JpqwlFOZAwMmSGPNPEJRw9kDshjotndUB5S1UCfv_U4IoVn7WgvxeCS-BBxqyWfh7YTdf73EnmGwVYxVjlXaHCeeTZmUacnT4MQUAcbFjTq6BBlboAQGWP2FZWpd6HNnruv744VeWmfgLk9z5567wFhwuXMkmE2xvDo4wP80xutjUfsePx5YkLxhY1XsWqTZr19tInxJWWq8RLZsWPmtq5wZ5ucBMasCLpOABenYZdSAcQNhC73wLS0Z2s1HQhBoIl7lr1p372LZs_Seu1u_8Fo7DoJqRpKaNoc2_JUMmn7TUZS8zLyzxgeq8R8iNbRP20DwDBNXocsTDBKaQrtB-QiEPySQtJa4G61XeNZyh5aGzfoWZ9OmjZG9pbbehcqwIrt-ESjPyeT6sfSrvOfTZr7fBXwpUs2rS4BrlNse5g_h8CQiik8aaOTOEPkXiyg4s5DewRlgDZHS-3g-YXPUIBNO62_HxknkMpkJvKW-tkvDbgtxvy4nG80ul6W_KeRsoEKDTRYNKZWxXjZITNa0h6agnwNCJKEbFg3Qhre394c0i60mfP9YIgKTXrCX3Yt2eX-6mPzYmLbSbV5jH69v6WZqYV2WAj-9DU0diR4hOfYQaJnBZhTtKb-SQsYiFuN1BDJ3v9eM9K8hq91NBdCHVa-Thk9Dov-JkcTZnZGRRyW5yXHUV4NOEltBXh8GkjjDvs5Yo3u-2rPCXjK1aGPSI1W8BaUJLQY5sbfAVCAuUHBv-Vlh5Qamt-lgeKguhqTSuy-tjabOb5kiBOG7xGQt3z-XYXtnWFDCii-5h11XfZsQ-xQxy8gSfdMz4hDK9Nw_VQt6fzWiQY0Th_dHzVki0MUfVfsDUjgblhD6j0wgbs3zdj-GM3rtt8oit0wXx11bIOaOKgf07tP0wimVXMRqRWe7LCUAKTE5PkRKU1x_h4iusrzi5uwKDhc4SmRwm6KssNrmCAkiNDZCREVKd3yMnrjA4PAGDzdKWVplcHJ6jKmrsbrEztHd9QAAAAAAAAAAAAAAABIfMEQ',\n      json: {\n        payload: 'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',\n        signatures: [\n          {\n            protected:\n              'eyJhbGciOiJNTC1EU0EtNDQiLCJraWQiOiJUNHhsNzBTN01UNlplcTZyOVY5ZlBKR1ZuNzZ3Zm5YSjIxLWd5bzBHdTZvIn0',\n            signature:\n              'knI1Q_9CIzLH5Xy94Kkc7WVKqZcAgtJ3mNf0GUj1uLA6YXAWFJfXkh-zQxUtEl3UIC7zPCiUwKTDR6ZsuUmFj8Ctb_6aH64hElN7weS_1m5okCy8GqHNL2lsfclCH3Y2f4QNP-DLVS1XsuboDA7Dw3ir2IdYKIfWJyIU7ROHgd24nuun1zJbxcLJC2EKt2M8R0wZudcIE9nm5oPzYXq0z-hPsKoXp9leVYkqgMmO9Lo8SP_1YYIEth3B8v-GuP249KDTFRKPjISmK4aPCknjtjihHsQVv2XePXxKExatHl4qhsiiW-y-EJXa1Kfw4WYpLA7B4_5Ids--cIJmIx7f6xxAWKh5qoBWq1QIOaaFuzsAraRW3NOEuzThew1En85gI3GcRTZGp-VDGyxHm0Al04cyWo2bxAVOF0fbDc265iP2mCNw6Qg10jIJeAhGB4OAMYcBUWJAG0l1MN1U_koEmGh5dXKnQTRl461ea_Cq3DLkcA2Dj2woWUFyDTmQ8oO_yheASfJacyRm7_suj88z5XFNo8F53P8OxTG9xUPlrwvH-TAq7AH3NU4SNXApyVKTU3zhx1tJ34nlTILcTujXVJVo_f0DZfUxr6JSCYqvy4z1Kl0wDQzd55aopyFtQxvOPhcCHbAN34g2Ug750Jm835fl7NOxcqoMbuTcgH68kr37M-Pdh2K9WazXUJgCupgdIWW8WjfOjmTiF59CrVtfVtK2qDzF40OENCfqtNPQlZe5cN5p0P8arj4USB8HCPh7NdqQBAeWrw0wsYhdiM39lrSkA8mLRYMhZnqKGCTPCrHXDdEjRKYRNaqIUT44laYl5c27K0v-ozjKPu6tzEhkYSC4XZ3LehEFtmAzOE0mHbhKMgXqjoPJjOrGIPibX3jwK8_Q5RmMOXtXo8R3vXfBaUdQoLeeyywNYE0nIcsl4z5a8_utwEFiVf0VK2pdviyiOPVSi3zOMAmqz6gFhVy8aMMQOWZAEAuTyDw7ZWG6diwptmrgSXZotW63I19S2ZH7keCXRIq_pFLuYhOuG6dD4MkouILRdC9bXZMLrNDq7COpUOO86aQVlYd0pR935WpUw-V6obSRnHlRFZSmUSIB7h1Q0ImciRzojN93Xhw7qpzGzdzDEO3OOTayXaSG_0YHQyy-eH4hBbmgt_LBx120g1eY4XHeHFRfTfetHkL5ZZusX1jQ_nk9ez4XBG_6hRtTNSuVBsYlH8-KUuR5-qTP8dkvRf8Wk2hHoUr2sz5YO_xDFCMMTrt8ahiMyfjo5ih5Fwo3riFbFUGKibniTLXspFd4spcNK_WchlZLRgkPK4jh6Z_X8JJkHxvQhpyouHQFyGxgBrl24x-_EB1zbWMhJthmm8DiKt-nzKaJz8Cju1-HwCpg76CRqRsEz2hyKEpbb4M5KQSj3AsENCroVmQ5QIv3K2XNRkve4vjBmP6sV2b6GSY_UeRvPElA7SUgBGTKbn-c0aYhBuB8plPhRTBa55_cFqAmNmavF1-fdMktJuIaH2f-K0zZCzbHw54998T7kIWgyMsyGCAvynEB_khOqwT7tCjg5HQ8SIjdnRYW0kjZfjt5LJbGA-PnRo8gPVQVGeYDP2vsSXhNJY94AitKCY1srcSsuYDrhNBKrnoJ1uEsMPVHsgFw_ZHMyAEaVQughSNW4fm8q6_1Nv4zLutDITzmAL6a6i6-WS6QRIs_4VUtwr5cXXIFDDeHVWeGcNivQ6W9urEUP4crguiq7z_DTiYaGfUksub-T7mw0zU8ZoOSd5pUTpJLv-IYIUAl6CscHvunnRLEKqpW1Sa1dcFZs5VP4AfR3mg7wX4Vlq1AHnpFxE2L1LZiKoTc9jDEOvTDkxr86gMkwMm6RdyPF_q48AVJ1br8Qp88-4B84X52zZ5cw-IJYe-HiVJ29LpeYm340_rWivpy-UB5i9TKlMrxf94y1okzZTPbP3_v1_XX0nE7RTLz98EA96euJ7l3EpbEqks7mh6i1FJNnvvlM_u29sYobJ6PUT-i1VlQnF_JBARKEz74pBXm1l5Y5Lo15rsIlaQHinUBCO8fHCHI59LAfKusN4JmodDqLYwkWijEL_sfrC6LtrbXqpM1pw09zSrs_tS1RQ-LnWHuPrU5KLCzv53JKrh8lU_cdBowe_F-Ib_Ui4bQ2FME-0mnyG0XijHUsrGMZ9dfowvIkr83JpqwlFOZAwMmSGPNPEJRw9kDshjotndUB5S1UCfv_U4IoVn7WgvxeCS-BBxqyWfh7YTdf73EnmGwVYxVjlXaHCeeTZmUacnT4MQUAcbFjTq6BBlboAQGWP2FZWpd6HNnruv744VeWmfgLk9z5567wFhwuXMkmE2xvDo4wP80xutjUfsePx5YkLxhY1XsWqTZr19tInxJWWq8RLZsWPmtq5wZ5ucBMasCLpOABenYZdSAcQNhC73wLS0Z2s1HQhBoIl7lr1p372LZs_Seu1u_8Fo7DoJqRpKaNoc2_JUMmn7TUZS8zLyzxgeq8R8iNbRP20DwDBNXocsTDBKaQrtB-QiEPySQtJa4G61XeNZyh5aGzfoWZ9OmjZG9pbbehcqwIrt-ESjPyeT6sfSrvOfTZr7fBXwpUs2rS4BrlNse5g_h8CQiik8aaOTOEPkXiyg4s5DewRlgDZHS-3g-YXPUIBNO62_HxknkMpkJvKW-tkvDbgtxvy4nG80ul6W_KeRsoEKDTRYNKZWxXjZITNa0h6agnwNCJKEbFg3Qhre394c0i60mfP9YIgKTXrCX3Yt2eX-6mPzYmLbSbV5jH69v6WZqYV2WAj-9DU0diR4hOfYQaJnBZhTtKb-SQsYiFuN1BDJ3v9eM9K8hq91NBdCHVa-Thk9Dov-JkcTZnZGRRyW5yXHUV4NOEltBXh8GkjjDvs5Yo3u-2rPCXjK1aGPSI1W8BaUJLQY5sbfAVCAuUHBv-Vlh5Qamt-lgeKguhqTSuy-tjabOb5kiBOG7xGQt3z-XYXtnWFDCii-5h11XfZsQ-xQxy8gSfdMz4hDK9Nw_VQt6fzWiQY0Th_dHzVki0MUfVfsDUjgblhD6j0wgbs3zdj-GM3rtt8oit0wXx11bIOaOKgf07tP0wimVXMRqRWe7LCUAKTE5PkRKU1x_h4iusrzi5uwKDhc4SmRwm6KssNrmCAkiNDZCREVKd3yMnrjA4PAGDzdKWVplcHJ6jKmrsbrEztHd9QAAAAAAAAAAAAAAABIfMEQ',\n          },\n        ],\n      },\n      json_flat: {\n        payload: 'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',\n        protected:\n          'eyJhbGciOiJNTC1EU0EtNDQiLCJraWQiOiJUNHhsNzBTN01UNlplcTZyOVY5ZlBKR1ZuNzZ3Zm5YSjIxLWd5bzBHdTZvIn0',\n        signature:\n          'knI1Q_9CIzLH5Xy94Kkc7WVKqZcAgtJ3mNf0GUj1uLA6YXAWFJfXkh-zQxUtEl3UIC7zPCiUwKTDR6ZsuUmFj8Ctb_6aH64hElN7weS_1m5okCy8GqHNL2lsfclCH3Y2f4QNP-DLVS1XsuboDA7Dw3ir2IdYKIfWJyIU7ROHgd24nuun1zJbxcLJC2EKt2M8R0wZudcIE9nm5oPzYXq0z-hPsKoXp9leVYkqgMmO9Lo8SP_1YYIEth3B8v-GuP249KDTFRKPjISmK4aPCknjtjihHsQVv2XePXxKExatHl4qhsiiW-y-EJXa1Kfw4WYpLA7B4_5Ids--cIJmIx7f6xxAWKh5qoBWq1QIOaaFuzsAraRW3NOEuzThew1En85gI3GcRTZGp-VDGyxHm0Al04cyWo2bxAVOF0fbDc265iP2mCNw6Qg10jIJeAhGB4OAMYcBUWJAG0l1MN1U_koEmGh5dXKnQTRl461ea_Cq3DLkcA2Dj2woWUFyDTmQ8oO_yheASfJacyRm7_suj88z5XFNo8F53P8OxTG9xUPlrwvH-TAq7AH3NU4SNXApyVKTU3zhx1tJ34nlTILcTujXVJVo_f0DZfUxr6JSCYqvy4z1Kl0wDQzd55aopyFtQxvOPhcCHbAN34g2Ug750Jm835fl7NOxcqoMbuTcgH68kr37M-Pdh2K9WazXUJgCupgdIWW8WjfOjmTiF59CrVtfVtK2qDzF40OENCfqtNPQlZe5cN5p0P8arj4USB8HCPh7NdqQBAeWrw0wsYhdiM39lrSkA8mLRYMhZnqKGCTPCrHXDdEjRKYRNaqIUT44laYl5c27K0v-ozjKPu6tzEhkYSC4XZ3LehEFtmAzOE0mHbhKMgXqjoPJjOrGIPibX3jwK8_Q5RmMOXtXo8R3vXfBaUdQoLeeyywNYE0nIcsl4z5a8_utwEFiVf0VK2pdviyiOPVSi3zOMAmqz6gFhVy8aMMQOWZAEAuTyDw7ZWG6diwptmrgSXZotW63I19S2ZH7keCXRIq_pFLuYhOuG6dD4MkouILRdC9bXZMLrNDq7COpUOO86aQVlYd0pR935WpUw-V6obSRnHlRFZSmUSIB7h1Q0ImciRzojN93Xhw7qpzGzdzDEO3OOTayXaSG_0YHQyy-eH4hBbmgt_LBx120g1eY4XHeHFRfTfetHkL5ZZusX1jQ_nk9ez4XBG_6hRtTNSuVBsYlH8-KUuR5-qTP8dkvRf8Wk2hHoUr2sz5YO_xDFCMMTrt8ahiMyfjo5ih5Fwo3riFbFUGKibniTLXspFd4spcNK_WchlZLRgkPK4jh6Z_X8JJkHxvQhpyouHQFyGxgBrl24x-_EB1zbWMhJthmm8DiKt-nzKaJz8Cju1-HwCpg76CRqRsEz2hyKEpbb4M5KQSj3AsENCroVmQ5QIv3K2XNRkve4vjBmP6sV2b6GSY_UeRvPElA7SUgBGTKbn-c0aYhBuB8plPhRTBa55_cFqAmNmavF1-fdMktJuIaH2f-K0zZCzbHw54998T7kIWgyMsyGCAvynEB_khOqwT7tCjg5HQ8SIjdnRYW0kjZfjt5LJbGA-PnRo8gPVQVGeYDP2vsSXhNJY94AitKCY1srcSsuYDrhNBKrnoJ1uEsMPVHsgFw_ZHMyAEaVQughSNW4fm8q6_1Nv4zLutDITzmAL6a6i6-WS6QRIs_4VUtwr5cXXIFDDeHVWeGcNivQ6W9urEUP4crguiq7z_DTiYaGfUksub-T7mw0zU8ZoOSd5pUTpJLv-IYIUAl6CscHvunnRLEKqpW1Sa1dcFZs5VP4AfR3mg7wX4Vlq1AHnpFxE2L1LZiKoTc9jDEOvTDkxr86gMkwMm6RdyPF_q48AVJ1br8Qp88-4B84X52zZ5cw-IJYe-HiVJ29LpeYm340_rWivpy-UB5i9TKlMrxf94y1okzZTPbP3_v1_XX0nE7RTLz98EA96euJ7l3EpbEqks7mh6i1FJNnvvlM_u29sYobJ6PUT-i1VlQnF_JBARKEz74pBXm1l5Y5Lo15rsIlaQHinUBCO8fHCHI59LAfKusN4JmodDqLYwkWijEL_sfrC6LtrbXqpM1pw09zSrs_tS1RQ-LnWHuPrU5KLCzv53JKrh8lU_cdBowe_F-Ib_Ui4bQ2FME-0mnyG0XijHUsrGMZ9dfowvIkr83JpqwlFOZAwMmSGPNPEJRw9kDshjotndUB5S1UCfv_U4IoVn7WgvxeCS-BBxqyWfh7YTdf73EnmGwVYxVjlXaHCeeTZmUacnT4MQUAcbFjTq6BBlboAQGWP2FZWpd6HNnruv744VeWmfgLk9z5567wFhwuXMkmE2xvDo4wP80xutjUfsePx5YkLxhY1XsWqTZr19tInxJWWq8RLZsWPmtq5wZ5ucBMasCLpOABenYZdSAcQNhC73wLS0Z2s1HQhBoIl7lr1p372LZs_Seu1u_8Fo7DoJqRpKaNoc2_JUMmn7TUZS8zLyzxgeq8R8iNbRP20DwDBNXocsTDBKaQrtB-QiEPySQtJa4G61XeNZyh5aGzfoWZ9OmjZG9pbbehcqwIrt-ESjPyeT6sfSrvOfTZr7fBXwpUs2rS4BrlNse5g_h8CQiik8aaOTOEPkXiyg4s5DewRlgDZHS-3g-YXPUIBNO62_HxknkMpkJvKW-tkvDbgtxvy4nG80ul6W_KeRsoEKDTRYNKZWxXjZITNa0h6agnwNCJKEbFg3Qhre394c0i60mfP9YIgKTXrCX3Yt2eX-6mPzYmLbSbV5jH69v6WZqYV2WAj-9DU0diR4hOfYQaJnBZhTtKb-SQsYiFuN1BDJ3v9eM9K8hq91NBdCHVa-Thk9Dov-JkcTZnZGRRyW5yXHUV4NOEltBXh8GkjjDvs5Yo3u-2rPCXjK1aGPSI1W8BaUJLQY5sbfAVCAuUHBv-Vlh5Qamt-lgeKguhqTSuy-tjabOb5kiBOG7xGQt3z-XYXtnWFDCii-5h11XfZsQ-xQxy8gSfdMz4hDK9Nw_VQt6fzWiQY0Th_dHzVki0MUfVfsDUjgblhD6j0wgbs3zdj-GM3rtt8oit0wXx11bIOaOKgf07tP0wimVXMRqRWe7LCUAKTE5PkRKU1x_h4iusrzi5uwKDhc4SmRwm6KssNrmCAkiNDZCREVKd3yMnrjA4PAGDzdKWVplcHJ6jKmrsbrEztHd9QAAAAAAAAAAAAAAABIfMEQ',\n      },\n    },\n  },\n  {\n    title: 'ietf-cose-dilithium - ML-DSA-65',\n    deterministic: false,\n    input: {\n      payload: 'It’s a dangerous business, Frodo, going out your door.',\n      key: {\n        kty: 'AKP',\n        alg: 'ML-DSA-65',\n        pub: 'QksvJn5Y1bO0TXGs_Gpla7JpUNV8YdsciAvPof6rRD8JQquL2619cIq7w1YHj22ZolInH-YsdAkeuUr7m5JkxQqIjg3-2AzV-yy9NmfmDVOevkSTAhnNT67RXbs0VaJkgCufSbzkLudVD-_91GQqVa3mk4aKRgy-wD9PyZpOMLzP-opHXlOVOWZ067galJN1h4gPbb0nvxxPWp7kPN2LDlOzt_tJxzrfvC1PjFQwNSDCm_l-Ju5X2zQtlXyJOTZSLQlCtB2C7jdyoAVwrftUXBFDkisElvgmoKlwBks23fU0tfjhwc0LVWXqhGtFQx8GGBQ-zol3e7P2EXmtIClf4KbgYq5u7Lwu848qwaItyTt7EmM2IjxVth64wHlVQruy3GXnIurcaGb_qWg764qZmteoPl5uAWwuTDX292Sa071S7GfsHFxue5lydxIYvpVUu6dyfwuExEubCovYMfz_LJd5zNTKMMatdbBJg-Qd6JPuXznqc1UYC3CccEXCLTOgg_auB6EUdG0b_cy-5bkEOHm7Wi4SDipGNig_ShzUkkot5qSqPZnd2I9IqqToi_0ep2nYLBB3ny3teW21Qpccoom3aGPt5Zl7fpzhg7Q8zsJ4sQ2SuHRCzgQ1uxYlFx21VUtHAjnFDSoMOkGyo4gH2wcLR7-z59EPPNl51pljyNefgCnMSkjrBPyz1wiET-uqi23f8Bq2TVk1jmUFxOwdfLsU7SIS30WOzvwD_gMDexUFpMlEQyL1-Y36kaTLjEWGCi2tx1FTULttQx5JpryPW6lW5oKw5RMyGpfRliYCiRyQePYqipZGoxOHpvCWhCZIN4meDY7H0RxWWQEpiyCzRQgWkOtMViwao6Jb7wZWbLNMebwLJeQJXWunk-gTEeQaMykVJobwDUiX-E_E7fSybVRTZXherY1jrvZKh8C5Gi5VADg5Vs319uN8-dVILRyOOlvjjxclmsRcn6HEvTvxd9MS7lKm2gI8BXIqhzgnTdqNGwTpmDHPV8hygqJWxWXCltBSSgY6OkGkioMAmXjZjYq_Ya9o6AE7WU_hUdm-wZmQLExwtJWEIBdDxrUxA9L9JL3weNyQtaGItPjXcheZiNBBbJTUxXwIYLnXtT1M0mHzMqGFFWXVKsN_AIdHyv4yDzY9m-tuQRfbQ_2K7r5eDOL1Tj8DZ-s8yXG74MMBqOUvlglJNgNcbuPKLRPbSDoN0E3BYkfeDgiUrXy34a5-vU-PkAWCsgAh539wJUUBxqw90V1Du7eTHFKDJEMSFYwusbPhEX4ZTwoeTHg--8Ysn4HCFWLQ00pfBCteqvMvMflcWwVfTnogcPsJb1bEFVSc3nTzhk6Ln8J-MplyS0Y5mGBEtVko_WlyeFsoDCWj4hqrgU7L-ww8vsCRSQfskH8lodiLzj0xmugiKjWUXbYq98x1zSnB9dmPy5P3UNwwMQdpebtR38N9I-jup4Bzok0-JsaOe7EORZ8ld7kAgDWa4K7BAxjc2eD540Apwxs-VLGFVkXbQgYYeDNG2tW1Xt20-XezJqZVUl6-IZXsqc7DijwNInO3fT5o8ZAcLKUUlzSlEXe8sIlHaxjLoJ-oubRtlKKUbzWOHeyxmYZSxYqQhSQj4sheedGXJEYWJ-Y5DRqB-xpy-cftxL10fdXIUhe1hWFBAoQU3b5xRY8KCytYnfLhsFF4O49xhnax3vuumLpJbCqTXpLureoKg5PvWfnpFPB0P-ZWQN35mBzqbb3ZV6U0rU55DvyXTuiZOK2Z1TxbaAd1OZMmg0cpuzewgueV-Nh_UubIqNto5RXCd7vqgqdXDUKAiWyYegYIkD4wbGMqIjxV8Oo2ggOcSj9UQPS1rD5u0rLckAzsxyty9Q5JsmKa0w8Eh7Jwe4Yob4xPVWWbJfm916avRgzDxXo5gmY7txdGFYHhlolJKdhBU9h6f0gtKEtbiUzhp4IWsqAR8riHQs7lLVEz6P537a4kL1r5FjfDf_yjJDBQmy_kdWMDqaNln-MlKK8eENjUO-qZGy0Ql4bMZtNbHXjfJUuSzapA-RqYfkqSLKgQUOW8NTDKhUk73yqCU3TQqDEKaGAoTsPscyMm7u_8QrvUK8kbc-XnxrWZ0BZJBjdinzh2w-QvjbWQ5mqFp4OMgY94__tIU8vvCUNJiYA1RdyodlfPfH5-avpxOCvBD6C7ZIDyQ-6huGEQEAb6DP8ydWIZQ8xY603DoEKKXkJWcP6CJo3nHFEdj_vcEbDQ-WESDpcQFa1fRIiGuALj-sEWcjGdSHyE8QATOcuWl4TLVzRPKAf4tCXx1zyvhJbXQu0jf0yfzVpOhPun4n-xqK4SxPBCeuJOkQ2VG9jDXWH4pnjbAcrqjveJqVti7huMXTLGuqU2uoihBw6mGqu_WSlOP2-XTEyRyvxbv2t-z9V6GPt1V9ceBukA0oGwtJqgD-q7NXFK8zhw7desI5PZMXf3nuVgbJ3xdvAlzkmm5f9RoqQS6_hqwPQEcclq1MEZ3yML5hc99TDtZWy9gGkhR0Hs3QJxxgP7bEqGFP-HjTPnJsrGaT6TjKP7qCxJlcFKLUr5AU_kxMULeUysWWtSGJ9mpxBvsyW1Juo',\n        priv: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\n      },\n      alg: 'ML-DSA-65',\n    },\n    signing: {\n      protected: {\n        alg: 'ML-DSA-65',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJNTC1EU0EtNjUiLCJraWQiOiJTdWl1MjlxYmZ1YUJhUjRBdHMtYzZYUUJlUEJfT3BBeEF3Y1RSXzBLWFZNIn0.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4.zmO9_0bLgJAegoVNymfRo4nGPK5lVtSFGnDbzfzYAD5mUEXpaBUg4itvZ8rAUZi4HLb59QqDQSBSpMXC0axajXOMV_YttfmwGgC6FMyaMRZkx-A92bGiNLutqX9jcwRLJqXjMkUGhz2YpHe_mV9QpxokRCH9K6jkyFZp4hZIwFXhRt1z0OGIa5rOoHKsxOCAUZhTXKiASb3vk9lUASW0-Y58WKT4rVmst7_dvk7FVbe9A9I21IH-Tqlg1zSMoI8ozh1aBSG92uPursBd5KRcOlJwhNUYJDgHScIHXM6Hzk6u98W5orKPHu1rDIK7rHJI4Zrui4wBjmQLsPE01LcZHRx4zexDCTMCGSojbL1FiT9CU3oUep4oWOytTEAf2eCi3qDD0iSrp5IslCueoNjtGOFSnUKlsnCeiZF-tNqTy1KpJ3ErTaNPcCzCvsEalhJwFa7NOWyQOEJUzcLaPY_VEFwcCX1Gk4bEI-1rLDiyZqkXgny-U2oRnll0d3u-e2S_Rg-_eL1H_XEbPs_km-822G7JY9li4muZ5KVvfQf_5hza1V4GweqvmeWuZL1gBU2HPS7x1tWL798ALOk1rMnxsvBOPiSLxAEdPoIuw0_qMlKjTavJcDFaihgCgGMUk5SjU65IWQS9t4rgxv9Idu0OCsozo9iCBqrVcnaOwUpkMhV6KeiXA7kQNcegVaMio40cjSyMiEkhGIOEOf8L6eohOh_bPPRYs-8NrZ-VOBJCa0ubJcDU1cTuGNCa7nWWxAqfVjcMyNDx9XHBYBnSOcFNfMP7S9nvqw3KC50U_t2PH5SfwS9w4DLvcgrlEP_gwSgOXuf-i0tRGLQly3IMB7O8QOnkofyFaCUDZeurFkGTpoBfT6lzbJznQAMIDPNcWUsRlNTXsH7atC1nxl4xDJLmmPLCxiErfxbCW5gMWox0kLDwfsFj57hsXG75cZ4jiBbq9b0VjD7Vkf8xlc06ExdzBhGXz8oJiaT5WHDsuzGtrFmh6diN1cO4Cxjr6KdNE8IlyxsfXxQ4AI-0ke3gMyi0DOGeHgHuNc-JHD7oZ6njUMSTBkR1aUMNT7n_2nfFTDCdqW1HaMsMwIHfLOk6dayKXE1oMqY5Op8S5k_SAaknR0vNxmhlTA5h3bZJ28NZxM6R7D00_eBEYrH20rmRP7G7kXKzLvmWeaKAh4oQHiqjVhgauiePDRiMmjx0OhdQnMCtO8PWbx06SiviRn_5hswdVV08B48MVHqbM2AxCLLJYinC2Ep0302Uo0DI-rTNZ1Znn58kM7VCskcxDLsH9AYvPz-HQr3H7Xg0ElwjYn-jJXgZ_cdnLFt4_TuKQdpw_qhvyrNjOx0Mdc-1PrwoWqpA9sSv_pS5lwI2qNVHI2Vj2mZHByod1QUeOQExf3SBjP_FHEAUzUu1OK8M-1SQZGzJT2su3a6ZnMnp0U5qdXyMONFoI2jJ2hDjt7QEQsLx-rvaLxZMJtc2z0MHdwJGAC_kug7XjH3SWQZzBu7zzreIaSwr2A2oobeZiAydwb8LX2QsY9Jr_NphGAMAqzrpkuaMyBd_pFTKMp9s0GYxwyG1ZD9uRuPI9imA4CS7bt-O8YvbWg6eQ-qa9OqDlxNt3Xc32TniQFVxVxN6PDY33XXU-Rpvd1w47NZ48nkyJzjD8Xlbvk9p2ynxWHr-Sto5HXZdru4j8ETUW7ri3mEG1m_dxAbAe2kVbsBp2I1vQppugbmRexuMRLdYFIKqNm0qpQoWTr_k2t5KHnWolrSbFH7Usm8Pwyi4sNhh4_yRHADO2q2o19zCCx2plDSMeYI74CQPRGLlK_GLM4E5Bzfny3E2eaE5_gQBTSGNHpQtJB0ipPwDjqsjDCXqXupCkRta1vxng4coi2-vWYvKu6mq9HhdovHAaWrZRyvuPPI4ZDN_NkmfQR8HogR6NLVhLlRp1cwMArSSDA3f8QlnjdbaeutxRXvFnCCjBk79ws8VGdWAuRmIWgoEFeVAVxkJjJ07zOW8I3kNfB6pnxsZmJwWAGqWc1UlPmkNBstmSXinAzbdl-W-kn1XRDuhzTafHnkCbKS5XgJKsWD2FrhcnCaxxRxuxIGxijofjD4ihmJoYDFh1FYs9IcC-szEfMSekanWOIZCHd1fVzTSbLr5bNaOXR2sO1muFX7w22m8pBVD3fyOHK2JnK4FBCnEBrruMIDaqqu8Z4xesAHKfxY67w-25eUuvVCGL3xpXSyp90684ICkG4STztP1shLVsxKDA-37sKKplqemERlMPY4vDM1Np8JlVawbSGIuom20g6p2KV_zpIPwx9vd1nAiaeZbryf3N5gtL-dOq-c6uZhTCx9OLBtLGE3BcAmn5JFjMGQFxyTL07BluNu24Kf-lttGj9jzbwPZYrok-SnMilXGFEqB3D3cKCOlWjsgg_3cUW1uMp4KlWQvkimV9Pd7cY70w607jcYBJ3MlFZ8EeWeYPZ9qu6xwidA8XlLHxXxfLIJOgfpU8MTppfxdnMhqNSvH_Hx57oDphbUks5K1Z8-O4dSnNqQ-ZWbhaAydYQFDKuUF6HYTAvaWhJmACxhTkTp2t6-P3bev-FcdFIdszJC9LxWtJ96LY_GV4Qvp0hiIdyP1BukWNHtsXK2Rxres3_4Cndg2BOGxVcKZ9YpQDCUy76GRbTCenqjD-SG5sVUEVha5yxbKArPr2-Xpgk8cuZBRSAdmPNRdxCgUtldfCLeL7xhJvryMouxfQ75PMBaImHcsMd95075ePt_VkClUaUj55Y9E81FbOEchPfud2w3TtSvRPvB8-RgY8sLJUAclxcUGE4PnKSZJ7TIBUtHD6uyZ0-nC5KGxbXZsBEzUeHns4ix0Wmo6-6vAM4PGK3qRA1VAhtKXyvNcAfVccVi8KJMK9Mz2eIOXPATvyRy34Ltrcg8tcgK0ftYqEWYpAZ2fVpZBXcYfTIinuLN0-qLra388EZuu59jvmRD7mUv1msMWVMGVeBoNP3lJaJGGWK8iYyu4q7Grq-6WXr5qCz_7kwAtVJdb-zW8U3jLJ3tRSYlyjlpzeVAGjDQ6Yni5y9x4BF-5QUqcoGMLLglyx2WOCELT8IW7nsV21QnqqAbtCzZ76UtEdmUuEOTyqiKQZ0lrjMRm3YrCvJKxtR5thhTRka708NzBvwSRs-JxGG__EWjHhT-aB4VL3IL_oz3mt3iQoszfA-SzHcKU1laZMBuUCyxks6KiJgQGZRPXyaxxDtqZdaRP8Ic5CmuPeyu3kafi0L6LFijsUxnSGxTpgu7hfvcmowQijfE9_ylvg8k_EbI2miG11giODVCYb7k9Yjyriwc9dSUUZ7XoiS24hWYUX6BGGQNN3wVHPkDkOVSDBYTjto99ulquryx4K_UMCu9sQVNxBfMh8tLN7O9-MXlnJbHfKfqFHiPGdIYOBpwuqJdAJiyiuSG3gJxMG_wuwNkBWoO--iOm6PIarCyvL8_P-tuUfT4zIgjJJ3o6YJhbo-q2K82ZFmHuILyzfDSGtHDZpZIR7XnRQWet90cJEHL5k653kvyEHJg0iUiE0iwNA5d_4gBq3vmw1J74hwAHx0Z_iYEcPS6hDGow8M8D7UJTZDkUV_86zj2YqGm_QC_aAeD__NP6sa61bI9-gTOzvYc0JiExKTDjOK9fIvHaV-HN4xr2vWner8o6jPyETvGM8D7aEezlUVOEFwALmhJPSMAq_Fk9JlcIUuC-ITJZNtNz9Awfiru3wkPja1bXN76WAuRHjia0x5ptgMCy2py_vSHZybfIS85ZjsOQ-i_e_niBzhyzXwzBaLEyEitbF4ZQx5c88lXKDMpe9tirAI6XAcqLf4UZkD8Wm2YV7hhVfxLQ1AWLekWE9DZljCtE-SbS1EWNGR8faXKCvaZznRyoqdWz8IN3w7KvaA_ZrEKkIXkkreztG6pI06DlDHCl_sU6rCOoyQf6y1AY77Ob4SdkSRoBHGgR6Uv-LrxHpyJ6trzccu0kqxubHrkW2yHcqe6enVf43zYwWKUeJJZ10bt3a92ziSne-3aj6v3guiKoJoLnV_9h8rUF6zorTWE-Tq58tYfb5SmGf4iCJ5cy9LTY0COIfwJtPkUmyBCZwUhWJnV24P5pOZPe_CckQ28xv5J7Zf4Bvqrq_rhubFEhTJ5JvdMfz8Whc56WSHX7GRKEMqXVp3pHohBvOyT9BmotzIlibVklJy4gzkzUcjJJOld-BOaM_cnMiHpoyKXSJAXTNwXngzEpbvDP2Y0fnrgqDpO3RR3gINaZLRmeG0WI4wWBMMfw8PHjpyV17C_1hmfRI-darbZcX7PD3N4Rw4lBACyk_wnOHBcAS-5cLZEzNmFmhc4iO4msz_seQ1N0drbB0NoUVWBmcY3pGC9TiY6f6Pn-FBUnQkuBhIyPtgAAAAAAAAAABgwVHCUv',\n      json: {\n        payload: 'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',\n        signatures: [\n          {\n            protected:\n              'eyJhbGciOiJNTC1EU0EtNjUiLCJraWQiOiJTdWl1MjlxYmZ1YUJhUjRBdHMtYzZYUUJlUEJfT3BBeEF3Y1RSXzBLWFZNIn0',\n            signature:\n              'zmO9_0bLgJAegoVNymfRo4nGPK5lVtSFGnDbzfzYAD5mUEXpaBUg4itvZ8rAUZi4HLb59QqDQSBSpMXC0axajXOMV_YttfmwGgC6FMyaMRZkx-A92bGiNLutqX9jcwRLJqXjMkUGhz2YpHe_mV9QpxokRCH9K6jkyFZp4hZIwFXhRt1z0OGIa5rOoHKsxOCAUZhTXKiASb3vk9lUASW0-Y58WKT4rVmst7_dvk7FVbe9A9I21IH-Tqlg1zSMoI8ozh1aBSG92uPursBd5KRcOlJwhNUYJDgHScIHXM6Hzk6u98W5orKPHu1rDIK7rHJI4Zrui4wBjmQLsPE01LcZHRx4zexDCTMCGSojbL1FiT9CU3oUep4oWOytTEAf2eCi3qDD0iSrp5IslCueoNjtGOFSnUKlsnCeiZF-tNqTy1KpJ3ErTaNPcCzCvsEalhJwFa7NOWyQOEJUzcLaPY_VEFwcCX1Gk4bEI-1rLDiyZqkXgny-U2oRnll0d3u-e2S_Rg-_eL1H_XEbPs_km-822G7JY9li4muZ5KVvfQf_5hza1V4GweqvmeWuZL1gBU2HPS7x1tWL798ALOk1rMnxsvBOPiSLxAEdPoIuw0_qMlKjTavJcDFaihgCgGMUk5SjU65IWQS9t4rgxv9Idu0OCsozo9iCBqrVcnaOwUpkMhV6KeiXA7kQNcegVaMio40cjSyMiEkhGIOEOf8L6eohOh_bPPRYs-8NrZ-VOBJCa0ubJcDU1cTuGNCa7nWWxAqfVjcMyNDx9XHBYBnSOcFNfMP7S9nvqw3KC50U_t2PH5SfwS9w4DLvcgrlEP_gwSgOXuf-i0tRGLQly3IMB7O8QOnkofyFaCUDZeurFkGTpoBfT6lzbJznQAMIDPNcWUsRlNTXsH7atC1nxl4xDJLmmPLCxiErfxbCW5gMWox0kLDwfsFj57hsXG75cZ4jiBbq9b0VjD7Vkf8xlc06ExdzBhGXz8oJiaT5WHDsuzGtrFmh6diN1cO4Cxjr6KdNE8IlyxsfXxQ4AI-0ke3gMyi0DOGeHgHuNc-JHD7oZ6njUMSTBkR1aUMNT7n_2nfFTDCdqW1HaMsMwIHfLOk6dayKXE1oMqY5Op8S5k_SAaknR0vNxmhlTA5h3bZJ28NZxM6R7D00_eBEYrH20rmRP7G7kXKzLvmWeaKAh4oQHiqjVhgauiePDRiMmjx0OhdQnMCtO8PWbx06SiviRn_5hswdVV08B48MVHqbM2AxCLLJYinC2Ep0302Uo0DI-rTNZ1Znn58kM7VCskcxDLsH9AYvPz-HQr3H7Xg0ElwjYn-jJXgZ_cdnLFt4_TuKQdpw_qhvyrNjOx0Mdc-1PrwoWqpA9sSv_pS5lwI2qNVHI2Vj2mZHByod1QUeOQExf3SBjP_FHEAUzUu1OK8M-1SQZGzJT2su3a6ZnMnp0U5qdXyMONFoI2jJ2hDjt7QEQsLx-rvaLxZMJtc2z0MHdwJGAC_kug7XjH3SWQZzBu7zzreIaSwr2A2oobeZiAydwb8LX2QsY9Jr_NphGAMAqzrpkuaMyBd_pFTKMp9s0GYxwyG1ZD9uRuPI9imA4CS7bt-O8YvbWg6eQ-qa9OqDlxNt3Xc32TniQFVxVxN6PDY33XXU-Rpvd1w47NZ48nkyJzjD8Xlbvk9p2ynxWHr-Sto5HXZdru4j8ETUW7ri3mEG1m_dxAbAe2kVbsBp2I1vQppugbmRexuMRLdYFIKqNm0qpQoWTr_k2t5KHnWolrSbFH7Usm8Pwyi4sNhh4_yRHADO2q2o19zCCx2plDSMeYI74CQPRGLlK_GLM4E5Bzfny3E2eaE5_gQBTSGNHpQtJB0ipPwDjqsjDCXqXupCkRta1vxng4coi2-vWYvKu6mq9HhdovHAaWrZRyvuPPI4ZDN_NkmfQR8HogR6NLVhLlRp1cwMArSSDA3f8QlnjdbaeutxRXvFnCCjBk79ws8VGdWAuRmIWgoEFeVAVxkJjJ07zOW8I3kNfB6pnxsZmJwWAGqWc1UlPmkNBstmSXinAzbdl-W-kn1XRDuhzTafHnkCbKS5XgJKsWD2FrhcnCaxxRxuxIGxijofjD4ihmJoYDFh1FYs9IcC-szEfMSekanWOIZCHd1fVzTSbLr5bNaOXR2sO1muFX7w22m8pBVD3fyOHK2JnK4FBCnEBrruMIDaqqu8Z4xesAHKfxY67w-25eUuvVCGL3xpXSyp90684ICkG4STztP1shLVsxKDA-37sKKplqemERlMPY4vDM1Np8JlVawbSGIuom20g6p2KV_zpIPwx9vd1nAiaeZbryf3N5gtL-dOq-c6uZhTCx9OLBtLGE3BcAmn5JFjMGQFxyTL07BluNu24Kf-lttGj9jzbwPZYrok-SnMilXGFEqB3D3cKCOlWjsgg_3cUW1uMp4KlWQvkimV9Pd7cY70w607jcYBJ3MlFZ8EeWeYPZ9qu6xwidA8XlLHxXxfLIJOgfpU8MTppfxdnMhqNSvH_Hx57oDphbUks5K1Z8-O4dSnNqQ-ZWbhaAydYQFDKuUF6HYTAvaWhJmACxhTkTp2t6-P3bev-FcdFIdszJC9LxWtJ96LY_GV4Qvp0hiIdyP1BukWNHtsXK2Rxres3_4Cndg2BOGxVcKZ9YpQDCUy76GRbTCenqjD-SG5sVUEVha5yxbKArPr2-Xpgk8cuZBRSAdmPNRdxCgUtldfCLeL7xhJvryMouxfQ75PMBaImHcsMd95075ePt_VkClUaUj55Y9E81FbOEchPfud2w3TtSvRPvB8-RgY8sLJUAclxcUGE4PnKSZJ7TIBUtHD6uyZ0-nC5KGxbXZsBEzUeHns4ix0Wmo6-6vAM4PGK3qRA1VAhtKXyvNcAfVccVi8KJMK9Mz2eIOXPATvyRy34Ltrcg8tcgK0ftYqEWYpAZ2fVpZBXcYfTIinuLN0-qLra388EZuu59jvmRD7mUv1msMWVMGVeBoNP3lJaJGGWK8iYyu4q7Grq-6WXr5qCz_7kwAtVJdb-zW8U3jLJ3tRSYlyjlpzeVAGjDQ6Yni5y9x4BF-5QUqcoGMLLglyx2WOCELT8IW7nsV21QnqqAbtCzZ76UtEdmUuEOTyqiKQZ0lrjMRm3YrCvJKxtR5thhTRka708NzBvwSRs-JxGG__EWjHhT-aB4VL3IL_oz3mt3iQoszfA-SzHcKU1laZMBuUCyxks6KiJgQGZRPXyaxxDtqZdaRP8Ic5CmuPeyu3kafi0L6LFijsUxnSGxTpgu7hfvcmowQijfE9_ylvg8k_EbI2miG11giODVCYb7k9Yjyriwc9dSUUZ7XoiS24hWYUX6BGGQNN3wVHPkDkOVSDBYTjto99ulquryx4K_UMCu9sQVNxBfMh8tLN7O9-MXlnJbHfKfqFHiPGdIYOBpwuqJdAJiyiuSG3gJxMG_wuwNkBWoO--iOm6PIarCyvL8_P-tuUfT4zIgjJJ3o6YJhbo-q2K82ZFmHuILyzfDSGtHDZpZIR7XnRQWet90cJEHL5k653kvyEHJg0iUiE0iwNA5d_4gBq3vmw1J74hwAHx0Z_iYEcPS6hDGow8M8D7UJTZDkUV_86zj2YqGm_QC_aAeD__NP6sa61bI9-gTOzvYc0JiExKTDjOK9fIvHaV-HN4xr2vWner8o6jPyETvGM8D7aEezlUVOEFwALmhJPSMAq_Fk9JlcIUuC-ITJZNtNz9Awfiru3wkPja1bXN76WAuRHjia0x5ptgMCy2py_vSHZybfIS85ZjsOQ-i_e_niBzhyzXwzBaLEyEitbF4ZQx5c88lXKDMpe9tirAI6XAcqLf4UZkD8Wm2YV7hhVfxLQ1AWLekWE9DZljCtE-SbS1EWNGR8faXKCvaZznRyoqdWz8IN3w7KvaA_ZrEKkIXkkreztG6pI06DlDHCl_sU6rCOoyQf6y1AY77Ob4SdkSRoBHGgR6Uv-LrxHpyJ6trzccu0kqxubHrkW2yHcqe6enVf43zYwWKUeJJZ10bt3a92ziSne-3aj6v3guiKoJoLnV_9h8rUF6zorTWE-Tq58tYfb5SmGf4iCJ5cy9LTY0COIfwJtPkUmyBCZwUhWJnV24P5pOZPe_CckQ28xv5J7Zf4Bvqrq_rhubFEhTJ5JvdMfz8Whc56WSHX7GRKEMqXVp3pHohBvOyT9BmotzIlibVklJy4gzkzUcjJJOld-BOaM_cnMiHpoyKXSJAXTNwXngzEpbvDP2Y0fnrgqDpO3RR3gINaZLRmeG0WI4wWBMMfw8PHjpyV17C_1hmfRI-darbZcX7PD3N4Rw4lBACyk_wnOHBcAS-5cLZEzNmFmhc4iO4msz_seQ1N0drbB0NoUVWBmcY3pGC9TiY6f6Pn-FBUnQkuBhIyPtgAAAAAAAAAABgwVHCUv',\n          },\n        ],\n      },\n      json_flat: {\n        payload: 'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',\n        protected:\n          'eyJhbGciOiJNTC1EU0EtNjUiLCJraWQiOiJTdWl1MjlxYmZ1YUJhUjRBdHMtYzZYUUJlUEJfT3BBeEF3Y1RSXzBLWFZNIn0',\n        signature:\n          'zmO9_0bLgJAegoVNymfRo4nGPK5lVtSFGnDbzfzYAD5mUEXpaBUg4itvZ8rAUZi4HLb59QqDQSBSpMXC0axajXOMV_YttfmwGgC6FMyaMRZkx-A92bGiNLutqX9jcwRLJqXjMkUGhz2YpHe_mV9QpxokRCH9K6jkyFZp4hZIwFXhRt1z0OGIa5rOoHKsxOCAUZhTXKiASb3vk9lUASW0-Y58WKT4rVmst7_dvk7FVbe9A9I21IH-Tqlg1zSMoI8ozh1aBSG92uPursBd5KRcOlJwhNUYJDgHScIHXM6Hzk6u98W5orKPHu1rDIK7rHJI4Zrui4wBjmQLsPE01LcZHRx4zexDCTMCGSojbL1FiT9CU3oUep4oWOytTEAf2eCi3qDD0iSrp5IslCueoNjtGOFSnUKlsnCeiZF-tNqTy1KpJ3ErTaNPcCzCvsEalhJwFa7NOWyQOEJUzcLaPY_VEFwcCX1Gk4bEI-1rLDiyZqkXgny-U2oRnll0d3u-e2S_Rg-_eL1H_XEbPs_km-822G7JY9li4muZ5KVvfQf_5hza1V4GweqvmeWuZL1gBU2HPS7x1tWL798ALOk1rMnxsvBOPiSLxAEdPoIuw0_qMlKjTavJcDFaihgCgGMUk5SjU65IWQS9t4rgxv9Idu0OCsozo9iCBqrVcnaOwUpkMhV6KeiXA7kQNcegVaMio40cjSyMiEkhGIOEOf8L6eohOh_bPPRYs-8NrZ-VOBJCa0ubJcDU1cTuGNCa7nWWxAqfVjcMyNDx9XHBYBnSOcFNfMP7S9nvqw3KC50U_t2PH5SfwS9w4DLvcgrlEP_gwSgOXuf-i0tRGLQly3IMB7O8QOnkofyFaCUDZeurFkGTpoBfT6lzbJznQAMIDPNcWUsRlNTXsH7atC1nxl4xDJLmmPLCxiErfxbCW5gMWox0kLDwfsFj57hsXG75cZ4jiBbq9b0VjD7Vkf8xlc06ExdzBhGXz8oJiaT5WHDsuzGtrFmh6diN1cO4Cxjr6KdNE8IlyxsfXxQ4AI-0ke3gMyi0DOGeHgHuNc-JHD7oZ6njUMSTBkR1aUMNT7n_2nfFTDCdqW1HaMsMwIHfLOk6dayKXE1oMqY5Op8S5k_SAaknR0vNxmhlTA5h3bZJ28NZxM6R7D00_eBEYrH20rmRP7G7kXKzLvmWeaKAh4oQHiqjVhgauiePDRiMmjx0OhdQnMCtO8PWbx06SiviRn_5hswdVV08B48MVHqbM2AxCLLJYinC2Ep0302Uo0DI-rTNZ1Znn58kM7VCskcxDLsH9AYvPz-HQr3H7Xg0ElwjYn-jJXgZ_cdnLFt4_TuKQdpw_qhvyrNjOx0Mdc-1PrwoWqpA9sSv_pS5lwI2qNVHI2Vj2mZHByod1QUeOQExf3SBjP_FHEAUzUu1OK8M-1SQZGzJT2su3a6ZnMnp0U5qdXyMONFoI2jJ2hDjt7QEQsLx-rvaLxZMJtc2z0MHdwJGAC_kug7XjH3SWQZzBu7zzreIaSwr2A2oobeZiAydwb8LX2QsY9Jr_NphGAMAqzrpkuaMyBd_pFTKMp9s0GYxwyG1ZD9uRuPI9imA4CS7bt-O8YvbWg6eQ-qa9OqDlxNt3Xc32TniQFVxVxN6PDY33XXU-Rpvd1w47NZ48nkyJzjD8Xlbvk9p2ynxWHr-Sto5HXZdru4j8ETUW7ri3mEG1m_dxAbAe2kVbsBp2I1vQppugbmRexuMRLdYFIKqNm0qpQoWTr_k2t5KHnWolrSbFH7Usm8Pwyi4sNhh4_yRHADO2q2o19zCCx2plDSMeYI74CQPRGLlK_GLM4E5Bzfny3E2eaE5_gQBTSGNHpQtJB0ipPwDjqsjDCXqXupCkRta1vxng4coi2-vWYvKu6mq9HhdovHAaWrZRyvuPPI4ZDN_NkmfQR8HogR6NLVhLlRp1cwMArSSDA3f8QlnjdbaeutxRXvFnCCjBk79ws8VGdWAuRmIWgoEFeVAVxkJjJ07zOW8I3kNfB6pnxsZmJwWAGqWc1UlPmkNBstmSXinAzbdl-W-kn1XRDuhzTafHnkCbKS5XgJKsWD2FrhcnCaxxRxuxIGxijofjD4ihmJoYDFh1FYs9IcC-szEfMSekanWOIZCHd1fVzTSbLr5bNaOXR2sO1muFX7w22m8pBVD3fyOHK2JnK4FBCnEBrruMIDaqqu8Z4xesAHKfxY67w-25eUuvVCGL3xpXSyp90684ICkG4STztP1shLVsxKDA-37sKKplqemERlMPY4vDM1Np8JlVawbSGIuom20g6p2KV_zpIPwx9vd1nAiaeZbryf3N5gtL-dOq-c6uZhTCx9OLBtLGE3BcAmn5JFjMGQFxyTL07BluNu24Kf-lttGj9jzbwPZYrok-SnMilXGFEqB3D3cKCOlWjsgg_3cUW1uMp4KlWQvkimV9Pd7cY70w607jcYBJ3MlFZ8EeWeYPZ9qu6xwidA8XlLHxXxfLIJOgfpU8MTppfxdnMhqNSvH_Hx57oDphbUks5K1Z8-O4dSnNqQ-ZWbhaAydYQFDKuUF6HYTAvaWhJmACxhTkTp2t6-P3bev-FcdFIdszJC9LxWtJ96LY_GV4Qvp0hiIdyP1BukWNHtsXK2Rxres3_4Cndg2BOGxVcKZ9YpQDCUy76GRbTCenqjD-SG5sVUEVha5yxbKArPr2-Xpgk8cuZBRSAdmPNRdxCgUtldfCLeL7xhJvryMouxfQ75PMBaImHcsMd95075ePt_VkClUaUj55Y9E81FbOEchPfud2w3TtSvRPvB8-RgY8sLJUAclxcUGE4PnKSZJ7TIBUtHD6uyZ0-nC5KGxbXZsBEzUeHns4ix0Wmo6-6vAM4PGK3qRA1VAhtKXyvNcAfVccVi8KJMK9Mz2eIOXPATvyRy34Ltrcg8tcgK0ftYqEWYpAZ2fVpZBXcYfTIinuLN0-qLra388EZuu59jvmRD7mUv1msMWVMGVeBoNP3lJaJGGWK8iYyu4q7Grq-6WXr5qCz_7kwAtVJdb-zW8U3jLJ3tRSYlyjlpzeVAGjDQ6Yni5y9x4BF-5QUqcoGMLLglyx2WOCELT8IW7nsV21QnqqAbtCzZ76UtEdmUuEOTyqiKQZ0lrjMRm3YrCvJKxtR5thhTRka708NzBvwSRs-JxGG__EWjHhT-aB4VL3IL_oz3mt3iQoszfA-SzHcKU1laZMBuUCyxks6KiJgQGZRPXyaxxDtqZdaRP8Ic5CmuPeyu3kafi0L6LFijsUxnSGxTpgu7hfvcmowQijfE9_ylvg8k_EbI2miG11giODVCYb7k9Yjyriwc9dSUUZ7XoiS24hWYUX6BGGQNN3wVHPkDkOVSDBYTjto99ulquryx4K_UMCu9sQVNxBfMh8tLN7O9-MXlnJbHfKfqFHiPGdIYOBpwuqJdAJiyiuSG3gJxMG_wuwNkBWoO--iOm6PIarCyvL8_P-tuUfT4zIgjJJ3o6YJhbo-q2K82ZFmHuILyzfDSGtHDZpZIR7XnRQWet90cJEHL5k653kvyEHJg0iUiE0iwNA5d_4gBq3vmw1J74hwAHx0Z_iYEcPS6hDGow8M8D7UJTZDkUV_86zj2YqGm_QC_aAeD__NP6sa61bI9-gTOzvYc0JiExKTDjOK9fIvHaV-HN4xr2vWner8o6jPyETvGM8D7aEezlUVOEFwALmhJPSMAq_Fk9JlcIUuC-ITJZNtNz9Awfiru3wkPja1bXN76WAuRHjia0x5ptgMCy2py_vSHZybfIS85ZjsOQ-i_e_niBzhyzXwzBaLEyEitbF4ZQx5c88lXKDMpe9tirAI6XAcqLf4UZkD8Wm2YV7hhVfxLQ1AWLekWE9DZljCtE-SbS1EWNGR8faXKCvaZznRyoqdWz8IN3w7KvaA_ZrEKkIXkkreztG6pI06DlDHCl_sU6rCOoyQf6y1AY77Ob4SdkSRoBHGgR6Uv-LrxHpyJ6trzccu0kqxubHrkW2yHcqe6enVf43zYwWKUeJJZ10bt3a92ziSne-3aj6v3guiKoJoLnV_9h8rUF6zorTWE-Tq58tYfb5SmGf4iCJ5cy9LTY0COIfwJtPkUmyBCZwUhWJnV24P5pOZPe_CckQ28xv5J7Zf4Bvqrq_rhubFEhTJ5JvdMfz8Whc56WSHX7GRKEMqXVp3pHohBvOyT9BmotzIlibVklJy4gzkzUcjJJOld-BOaM_cnMiHpoyKXSJAXTNwXngzEpbvDP2Y0fnrgqDpO3RR3gINaZLRmeG0WI4wWBMMfw8PHjpyV17C_1hmfRI-darbZcX7PD3N4Rw4lBACyk_wnOHBcAS-5cLZEzNmFmhc4iO4msz_seQ1N0drbB0NoUVWBmcY3pGC9TiY6f6Pn-FBUnQkuBhIyPtgAAAAAAAAAABgwVHCUv',\n      },\n    },\n  },\n  {\n    title: 'ietf-cose-dilithium - ML-DSA-87',\n    deterministic: false,\n    input: {\n      payload: 'It’s a dangerous business, Frodo, going out your door.',\n      key: {\n        kty: 'AKP',\n        alg: 'ML-DSA-87',\n        pub: '5F_8jMc9uIXcZi5ioYzY44AylxF_pWWIFKmFtf8dt7Roz8gruSnx2Gt37RT1rhamU2h3LOUZEkEBBeBFaXWukf22Q7US8STV5gvWi4x-Mf4Bx7DcZa5HBQHMVlpuHfz8_RJWVDPEr-3VEYIeLpYQxFJ14oNt7jXO1p1--mcv0eQxi-9etuiX6LRRqiAt7QQrKq73envj9pkUbaIpqL2z_6SWRFln51IXv7yQSPmVZEPYcx-DPrMN4Q2slv_-fPZeoERcPjHoYB4TO-ahAHZP4xluJncmRB8xdR-_mm9YgGRPTnJ15X3isPEF5NsFXVDdHJyTT931NbjeKLDHTARJ8iLNLtC7j7x3XM7oyUBmW0D3EvT34AdQ6eHkzZz_JdGUXD6bylPM1PEu7nWBhW69aPJoRZVuPnvrdh8P51vdMb_i-gGBEzl7OHvVnWKmi4r3-iRauTLmn3eOLO79ITBPu4CZ6hPY6lfBgTGXovda4lEHW1Ha04-FNmnp1fmKNlUJiUGZOhWUhg-6cf5TDuXCn1jyl4r2iMy3Wlg4o1nBEumOJahYOsjawfhh_Vjir7pd5aUuAgkE9bQrwIdONb788-YRloR2jzbgCPBHEhd86-YnYHOB5W6q7hYcFym43lHb3kdNSMxoJJ6icWK4eZPmDITtbMZCPLNnbZ61CyyrWjoEnvExOB1iP6b7y8nbHnzAJeoEGLna0sxszU6V-izsJP7spwMYp1Fxa3IT9j7b9lpjM4NX-Dj5TsBxgiwkhRJIiFEHs9HE6SRnjHYU6hrwOBBGGfKuNylAvs-mninLtf9sPiCke-Sk90usNMEzwApqcGrMxv_T2OT71pqZcE4Sg8hQ2MWNHldTzZWHuDxMNGy5pYE3IT7BCDTGat_iu1xQGo7y7K3Rtnej3xpt64br8HIsT1Aw4g-QGN1bb8U-6iT9kre1tAJf6umW0-SP1MZQ2C261-r5NmOWmFEvJiU9LvaEfIUY6FZcyaVJXG__V83nMjiCxUp9tHCrLa-P_Sv3lPp8aS2ef71TLuzB14gOLKCzIWEovii0qfHRUfrJeAiwvZi3tDphKprIZYEr_qxvR0YCd4QLUqOwh_kWynztwPdo6ivRnqIRVfhLSgTEAArSrgWHFU1WC8Ckd6T5MpqJhN0x6x8qBePZGHAdYwz8qa9h7wiNLFWBrLRj5DmQLl1CVxnpVrjW33MFso4P8n060N4ghdKSSZsZozkNQ5b7O6yajYy-rSp6QpD8msb8oEX5imFKRaOcviQ2D4TRT45HJxKs63Tb9FtT1JoORzfkdv_E1bL3zSR6oYbTt2Stnpz-7kVqc8KR2N45EkFKxDkRw3IXOte0cq81xoU87S_ntf4KiVZaszuqb2XN2SgxnXBl4EDnpehPmqkD92SAlLrQcTaxaSe47G28K-8MwoVt4eeVkj4UEsSfJN7rbCH2yKl2XJx5huDaS0xn2ODQyNRmgk-5I9hXMUiZDNLvEzx4zuyrcu2d0oXFo3ZoUtVFNCB__TQCf2x27ej9GjLXLDAEi7qnl9Xfb94n0IfeVyGte3-j6NP3DWv8OrLiUjNTaLv6Fay1yzfUaU6LI86-Jd6ckloiGhg7kE0_hd-ZKakZxU1vh0Vzc6DW7MFAPky75iCZlDXoBpZjTNGo5HR-mCW_ozblu60U9zZA8bn-voANuu_hYwxh-uY1sHTFZOqp2xicnnMChz_GTm1Je8XCkICYegeiHUryEHA6T6B_L9gW8S_R4ptMD0Sv6b1KHqqKeubwKltCWPUsr2En9iYypnz06DEL5Wp8KMhrLid2AMPpLI0j1CWGJExXHpBWjfIC8vbYH4YKVl-euRo8eDcuKosb5hxUGM9Jvy1siVXUpIKpkZt2YLP5pEBP_EVOoHPh5LJomrLMpORr1wBKbEkfom7npX1g817bK4IeYmZELI8zXUUtUkx3LgNTckwjx90Vt6oVXpFEICIUDF_LAVMUftzz6JUvbwOZo8iAZqcnVslAmRXeY_ZPp5eEHFfHlsb8VQ73Rd_p8XlFf5R1WuWiUGp2TzJ-VQvj3BTdQfOwSxR9RUk4xjqNabLqTFcQ7As246bHJXH6XVnd4DbEIDPfNa8FaWb_DNEgQAiXGqa6n7l7aFq5_6Kp0XeBBM0sOzJt4fy8JC6U0DEcMnWxKFDtMM7q06LubQYFCEEdQ5b1Qh2LbQZ898tegmeF--EZ4F4hvYebZPV8sM0ZcsKBXyCr585qs00PRxr0S6rReekGRBIvXzMojmid3dxc6DPpdV3x5zxlxaIBxO3i_6axknSSdxnS04_bemWqQ3CLf6mpSqfTIQJT1407GB4QINAAC9Ch3AXUR_n1jr64TGWzbIr8uDcnoVCJlOgmlXpmOwubigAzJattbWRi7k4QYBnA3_4QMjt73n2Co4-F_Qh4boYLpmwWG2SwcIw2PeXGr2LY2zwkPR4bcSyx1Z6UK5trQpWlpQCxgsvV_RvGzpN22RtHoihPH74K0cBIzCz7tK-jqeuWl1A7af7KmQ66fpRBr5ykTLOsa17WblkcIB_jDvqKfEcdxhPWJUwmOo4TIQS-xH8arLOy_NQFG2m14_yxwUemXC-QxLUYi6_FIcqwPBKjCdpQtadRdyftQSKO0SP-GxUvamMZzWI780rXuOBkq5kyYLy9QF9bf_-bL6QLpe1WMCQlOeXZaCPoncgYoT0WZ17jB52Xb2lPWsyXYK54npszkbKJ4OIqfvF8xqRXcVe22VwJuqT9Uy4-4KKQgQ7TXla7Gdm2H7mKl8YXQlsGCT2Ypc8O4t0Sfw7qYAuaDGf752Hbm3fl1bupcB2huIPlIaDP6IRR9XvTYIW2flbwYfhKLmoVKnG85uUi2qtqCjPOIuU3-peT0othfmwKQXaoOqO-V4r6wPL1VHxVFtIYmEdVt0RccUOvpOVR_OAHG9uHOzTmueK5557Qxp0ojtZCHyN-hgoMZJLrvdKkTCxPNo2-mZQbHoVh2FnThZ9JbO49dB8lKXP4_MU5xAnjXMgKXtbfI8w6ZWATE_XWgf2VQMUpGp4wpy44yWQTxHxh_4T9540BGwG0FU0bkgrwA_erseGZnepqdmz5_ScCs84O5Xr5MbYhJLCGGxY6O5GqS-ooB2w0Mt87KbbE4bpYje9CAHH8FX3pDrJyLsyasA3zxmk4OmGpG7Z70ofONJtHRe56R5287vFmuazEEutXn81kNzB-3aJT1ga3vnWZw4CSvFKoWYSA7auLgrHSHFZdITfOrgtmQmGbFhM9kSBdY1UCnpzf65oos3PZWRa2twfUxxLAnPNtrxpRGyvtsapw7ljUagZmuyh3hLCjhAxYmnoE1dbyIWvpCqSlEtVjL1yb_nuLEzgvmZuV02fHxGuWgHTOMVGXpf81Rce3eoBK3lapW1wkzezlk3tcA2bZOtA9qbxdsbVR37kemzQ9K1e3Y0OWhtSj',\n        priv: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\n      },\n      alg: 'ML-DSA-87',\n    },\n    signing: {\n      protected: {\n        alg: 'ML-DSA-87',\n      },\n    },\n    output: {\n      compact:\n        'eyJhbGciOiJNTC1EU0EtODciLCJraWQiOiJ0Um4xSk5Ja2dNc0FCVlFCbFhlREh4QUljY2xoLTJJWDBVZERFelB0NVhVIn0.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4.hmMrKkUgZwGPQV_WUoXUVq_Z9WOenDZbfMmHpKritl0btWi29TC8eIyQyT1FAuW2kg3h6ALsvCrjX5tn3QKFQZYC0sBdRt0VNiDm0BjyJ4jWcomSCgb0-cGXaLlODAz-njGridYfO1DpGMwHHshuKuvECv4qnX3XgZPE-6C8La43TZrYO8brzBXGiuyGMLq-TSmXavOeiadtpp6iTUqJDBgQSYvPB6PvipeCPlQH2ZQi8qkraxspi0lgy8Jh2aRYj44DX2ZKq-Ml-hfBJB4iHRpWmwPpEH7Ed4LkBIlaqZoPccrPgpGQpyz4_FcahrJc8CGGtTO5I34o5BcuZej7WOQvJ6mRmvYqIrYwoLs-3_YFZkVdX4KU38oprMvAHjObOhy_vZZArMnCgfYlCKrANbhOZG8O0BXgqow5Bqv_oRIztGQZMrivp_1CS0hELarwkwjdqyH5R747ndV26IQkeyn6y9daXRZIWxaC9KmAaDSm5-YsRVpiAAr0QmfaV51z065_r5qZmOMFIBERVi9Bbm_Z7ipJkoIL2SqVsePATfHeWB8huFpVFxdeEkJUPDuBtthax0HhxpRuECpFNJf2xA70Hp5C5VZIsi5EO21HuRpixiNKmXP5whhsn_uv_B7R4f4DX6X6A53lFrUfpFIrTfOQvBAvmEUUTSGcPeT-F7f_1lz34uFyN3ZT4FCeCh4n4yyZY1fSPVMNtOfK8GrLrRoWdi8gMk30oTKgb9zFkFU7uZhVEVRV86A_060bgFSHWDz5dlXLfyCoJsbsHlO9WBibTCkrMv6lnjh4czprro2prRtJAJB2jVwS1dv2mo4wP1lFYqY63yM9I9deU4fxy6mkwig7XwcVJskg8jX_0agATqmrKfYWMI4yGQ9fciYacgN8X2uSHqiPU1cgQ8VUGsSAsw4POdZpmcUt_DacVLT8-qwnq6NWpm8bqm_uUQu3JjqcHKLz7zWKopeLG_ZY7a45IqUQpwbMg9ICE1ZNTe5nsMHAJnevgLfWk14wnvVQyRVvlSvatdUTg0EjBc6P35a4lY12vIOq2ENpA-m52TfXeXxXK0vtZfT9SY33thi4EfZABWL_jQyiio6b6Akrh6_PgQ-bh2H2Fpu8Z3GImrbHodcbnqFpmKYlMLwxDHnKPxY7PpyyV8HsWfEjqVlAX56stAIIG4_owwzMZMcFwgucAP176TwjaXJqm9v2-DXisD2cNjyGlJ_rec670rv61thjiJF2uZrB9Z2zoQVYnc3Y9sJMMPPmunUcXpNVZWSsPlFDoPa1ABoFnRbP8rO-qbNGP5N7xY2DuPRYOp3CdyxeyDPmGBC2556FNeLRj-PhPAkd61fgXsQZyS9N2jHmFUIKbL8o-e3bQnqW7ebEn7zAjS_LQ2DtgIdIneUu84hh8AduoW9ky_aOpqvBUmdnHUwZHQiSSdeCPnEOssVBbuDd3gbcQf_VWvplwcjTTrJPsqqZpirjfVGPFUCVAz6kD0vhFcvTdQt6DGqys61xg_VOfj6wxpKsXuXDuqwaeb4KpGniHx-23nECgKG86N_1BBX8RRAvYnksxIIxIxgyrng-y44CV9FL_wGfP0Plx6JjSUFOL1gDZTc5NrAPoOztEo1FbJ2Lq8gqBR9Ku9Yza3aYANAJQvAraTXzA0t1j6qcmh-WtXeI1GE-8neOJtlRVbzT5RvPiRJZAVmu9Pg97wbLLQNPJoqIYp-c9mieGsDxAi75C2M1ArRnCa4kJJXrupgzQzzFefWyaRkIvC2MP9MwB_Z_NY3mp3opcNlT1TdKLr1sncLUkk3qJ0Pwyr-5dsKrC6aenapBHO7G0OnA0qTi8-Oy91VqJYYcVjcOUQaxNeMtnk-pLJL7j3MzqNiDkc-OfR19fcWvDmmd9Z8wtj20khL4mTDn7qTUo-PsVR7GnpqkImmEmE8sa4ZlPHa4_IcZGFbdcwp9xuOndINlzWGrIKywFPQ1x26zXDEa7fOx5f01aX8dIU_KWNAGdaZxPIlqLW5qbC6dipSqf9NwblZLJs5DCiLV8nHS-QM26xQJVUNH22n_3Z_8z1SA8AX8d7j0-g1Pf7NZC8e8Ipnm4B3YGpA7nn471aTbJb4OUamfgys17MV_hPDK_f7FF7NXp06-dtVYDmcs-87ZkrDuluOkUaRivKULwjEtSbiiKZAKirGfAOuwyCbbzygEpqYvEztABSmDYd_F_autklob_0deKuvvRYFpVCaxeaYQ7WIkpfBbMxeh9Qci7kPfgyB5H9ajWEJV3fgRk10Q1RaWyTUddQ_jWaluiDa3GD_t39sUrG7QhXc2Oz1NPPNoY6-A4jFbFCtXSF1muztqy0xaworcNiHY18yeL4Cw2iYLJ1Q3O4NnFo3E-wIXmYF4CLxZifr2Jkd6Ix1w-wlsN6vyCcDs8JeAgeJn0_Oahk1mgvRhVz8FFeidSdFqJBxGKbfZ32F_auJwrsLyjN_ShxTSFofyKQy2XCfoVMko4eu5o6md66xBmjZvTvItXL7f-eD0JxISBsBkZG3mFrApZKbdpI1lEa681ZbCxRTYpxUR7McTbs0Q5S9PCN5ElUz_axfeupIIbCTE4S0-ZQuIdQcQ2pn1j-4t2c04jtLE6WFI-1ASBCedlZmrZUiRegbezE01hMiFnfN32BhBu7ZcnlBCdWwj9hUfpEduJIgaA3acXhysGs40nqRzR9imvX9CBQYJZjrCHr-wORF6svmvF5FADRgwbM7Cc9puJgLBiQwXrhD43B6kjX_OXi5O2UNZFkAPr0WONBJsip8CgR6pt1u_mIKlIrYM9kM-idJGGT0DZ9UU4LMx0-9_2KCCkjDqgYN1rS9DA__GP9tS3dJ-XLSlk2URQuoHm4Xubv4vwgjUS7JzAxcQWHB0HtHFoZ3-tYVw_GRbRwyODm3E-N5O3L_R-pva9fvlPjkCNMrf2IlxAxBKML1gCxsSqhFr5yoPeW40LTxMF_dYPNLjC3l7mRRl_wfY_FhvayI7hrgCYfMgWeb-cXyx5eXumt9lMFOD3dQtEG1IUbdE7pVXG-barWK0Zl43DtQMNQzoCK_BLxfCsambyRRcI6E4QTfqe5lWtVf8Wi4KproenWyCjjzEjJQdWw4g-ae_bjGjfZCp38RgsXtWgI_tuzKyRF5WwjyN9VEoRXd8W2DctmBejHF2XDYzbMFkJ-384SokPX6intnlqBGMs0ssxriJhsFOA-vgDra6REx3DUMb8_u_Umc-zp4E6isX4D-eRYgElmj0ez945nqxp3YliO8mRLMW6E4OupLthfw4vmK3YqTAuXcnGxYrf7JqAkMfz5uAPi0SqPWDQZq7ycu9BmkMXAIhMb19XBDjL7hZGDwDRrn9yBBcYlPaFPNXjMJWJH_xxUKNsTFGg5-J_WdxXi8Zn6tDMxbxqqjIpw_FUaM00jJ2MhpbkzhEx7X85pBR47ScRgr6WJpf4ZLSFuV7NT1WI3PIBa_bYeCiq29fp3ShM-1bRFdJG_lGZd97TuAMF_QU6-KDXBv5i8kUZ1NXdJUz-YaA0RRVNFgMGM5n0pKB5IFncAPK-taTzHLIZJ9uuBdP2y2Hxwbw8YQlmy2-MT5XE5Ae_9kxuvIIlSzjpfLN9012HSnX4tZ8x3aWwof3E7s3jjzw7qbBtoUkYYpIGVOKf2EpmhEqevSlXYWpBYN3X2ZYjsrA9CL9PTvrPdyWLwKBmfh7cDJbjNXJSQLeKL7oHzicrllABzR9Ckkz7b24XGV1Klcat_Og4oB9qxiO2zJZWz2GDTAL0hosUlHLWnrQYvqFzzdIOzGlifwIyGgoRNb44IRMzzsErxuoqkdjZewVc4PzruHRlV3cWK6M7ZUiWLtxtMzas2sfAERy8BdS7ISLzj5PERoWyYXSW-898WD3ze5MJcpSsAYNEmPCBtdxF9l-Qz1LxuDa8hOCQ2Wzef1a2WFF5pCBaZRcAK_kef65xRst6WFpjWZGCLZUqHBhFDLEOd7Ikbw7d9V8dc4nAO65NQcxfT9JDUZadS2jmQJip8GLD4P9lGS1Ry-8rHCnMN7zXDp43TfyYhSgv9uj4xKi2wmAMMYBl0n2RNemx8nt-K_dknGgYYGOybDkg2uAUoXdxP33KfiRjbRpYqZVAiq0S45QLAIxxGiDJoZRnyIscdM6lryQtXj0PO67vRf6ifxC3wLv97HHUKergpXcAg-4_rNj_Zx_xiHMfCAe2q3DG1a_DcSmu5u1OPkBHmzHB9Vs8HV0E2-z44sl3Exqb5L8pMYpDnZ7QW-Qb1-S-zoESUy__AKhkRWPC7GmvmJJJHur6SRGSK0X2KyszkEYoe-8NhwpvLrYnNuVk7QknBS91KH2q8C0B8FKqcY40S5ILkImP9iOGIXYl5ZVRleoDBpH9BootWH2az5l7c_e-vfBGs7XpudoAq5wzhe_-AMBvKPCm0BoCX5B_NGUasXvEWobqUb61mpKCuVJdzVtexk-m8Jfvmdc8ooPJEYD_oosY5_S1LuHoc7GHLnoYdDVb2FhIPhOJCLQCef-Y3dtNThqOEo534Zg7R72nSeSQhdQ1hcBUsc50U2oF9OlOnV9z5hsfNwIxdUO9bdoXRYFmosmtpmDfGxAem0s5iPJ0EJ_8szlaX2pi6k6VP-ci-n7J8pEBwL2R3c-ei2iqB7JdLi7Gg6iXVMpQIFTxswh0HbgGtyZXgR_-AM91XRszm_kAlqAHTAJ7B-0Z5bJgMGEY2StBdhGzel_gNPVaxemC3DT0904GbCU2Z3avUHcedebI02_MdILdQxyXbw145KjqC15CqeaG--6x6WzpAuSjrFQRuz6Z5UyibW6Ay9R3P25c-gwmaRM8rPW5YkQtQdfzrtvGZ6wyhIcBXvbpU02OoChfRDF4xI2LvnaW3g6hQIUGe5lueI13ArYRAhZC0LHKPuVfv5OKeMqxYRtcN3YK6Ddc1t61rsA7MU1cAKzOGsiQ7aNyNBQHOV6z-W4-ws_DnZKYRMz0D_hwbeHO0ZKhciXng5VDCX4hyb47LExmO5N1mfihN3iHEkX_19rIgunfkSb9gd9B_AaazAttBEPPLtbsoZneQXBRl3PWiDpC_yXiLTWAd13AOBYHzBMKeJ4hplUqsAGTaGSztbpvV92wz_YX9kMEucHMu5hoM-TJbuWoheiiiKSFBNRK_g_rqXZo1UZjDOnHpHGJxOnlJBPp94Zvwh8sKLOpOd4qeOMLbnYKiag00al5x_3fBXq-KI0Y31OJfgDdCaKAQ0DUX71HN6XDOlvU1Iwh48iASJHdQGDmjhcS8YoeX9omwPiYhcbGJGzEVrn3H7h24eIf_7bVRpicMhjwghB0xtqTT0eVam1l8kr1-5kem7Dr2Kyqm2HpEwbi3KPXKYDXQRbHElEhazMCYr2wnjx_Bx2ai2uZa8uQyjN1zh1cjWHH0TicL2eAyc6YPKfKpmc5QwLrgT0ddQDhvXkCkN50fOR1Sbl56iFoAL8goFl3QA5wBk51vsDsquEt7nlz6sGTHzknENb-eEayrXnw-Q5FueFwqzoJpUrEYDXTxgOU8XVhrPv0Ot-BO6ORfzn3_1gREcHjhrc6RdF01NNqyzyVG0BdckywvAnzUGskWdCfP62dKdx46lAIRVPd3xG4tViaQ79GAeMVnqSeCLXbOyqfnJwhOT2fgQzLwxcj1tqGBBd3Pfx2d5-10WiL_mis0ven6golqaLq1EQsveb9AJpkYgJxdBeyHZXxNLMh4_XAuK1ZIs9F8Cz1vFEVcAFipev-cFyRvsdcNI2-HK2nOGkypEcuVATyLtA0jKeyPtE4TJ3_l8KXltEZjWycQAd_8Tj9is3wisC8bfzjll8UBjFZp-rzmCr8kA4cZih9gl27TiCmhyKhgMfDUIUmuDL_Rn9DLxEAT3Ebl1SW0ToCciNtKTH9oO-wnkPd-jg1HCooLcg-K_QkOTptJNZRFbXpooKqwH5Z9qsCxurZxnS_MscnE0qTa4EqrlpiDnj4FBs4q9SEPlKequfYzFmjQis1iwsReutf6pHmsvRmz9gx5vd6NMIkI05IeLNDElvlOGD04m1vR4ZISdmdHaAgaW9_AUPGx0vP1Rqe36cvebwUYSnzdbZ7y1s7PH7GXF5r7zNEzY9bHmXvsjb3N_u9BkenwkQfZGS6ez0AAAAAAAAAAALGSAlKzg7Qw',\n      json: {\n        payload: 'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',\n        signatures: [\n          {\n            protected:\n              'eyJhbGciOiJNTC1EU0EtODciLCJraWQiOiJ0Um4xSk5Ja2dNc0FCVlFCbFhlREh4QUljY2xoLTJJWDBVZERFelB0NVhVIn0',\n            signature:\n              'hmMrKkUgZwGPQV_WUoXUVq_Z9WOenDZbfMmHpKritl0btWi29TC8eIyQyT1FAuW2kg3h6ALsvCrjX5tn3QKFQZYC0sBdRt0VNiDm0BjyJ4jWcomSCgb0-cGXaLlODAz-njGridYfO1DpGMwHHshuKuvECv4qnX3XgZPE-6C8La43TZrYO8brzBXGiuyGMLq-TSmXavOeiadtpp6iTUqJDBgQSYvPB6PvipeCPlQH2ZQi8qkraxspi0lgy8Jh2aRYj44DX2ZKq-Ml-hfBJB4iHRpWmwPpEH7Ed4LkBIlaqZoPccrPgpGQpyz4_FcahrJc8CGGtTO5I34o5BcuZej7WOQvJ6mRmvYqIrYwoLs-3_YFZkVdX4KU38oprMvAHjObOhy_vZZArMnCgfYlCKrANbhOZG8O0BXgqow5Bqv_oRIztGQZMrivp_1CS0hELarwkwjdqyH5R747ndV26IQkeyn6y9daXRZIWxaC9KmAaDSm5-YsRVpiAAr0QmfaV51z065_r5qZmOMFIBERVi9Bbm_Z7ipJkoIL2SqVsePATfHeWB8huFpVFxdeEkJUPDuBtthax0HhxpRuECpFNJf2xA70Hp5C5VZIsi5EO21HuRpixiNKmXP5whhsn_uv_B7R4f4DX6X6A53lFrUfpFIrTfOQvBAvmEUUTSGcPeT-F7f_1lz34uFyN3ZT4FCeCh4n4yyZY1fSPVMNtOfK8GrLrRoWdi8gMk30oTKgb9zFkFU7uZhVEVRV86A_060bgFSHWDz5dlXLfyCoJsbsHlO9WBibTCkrMv6lnjh4czprro2prRtJAJB2jVwS1dv2mo4wP1lFYqY63yM9I9deU4fxy6mkwig7XwcVJskg8jX_0agATqmrKfYWMI4yGQ9fciYacgN8X2uSHqiPU1cgQ8VUGsSAsw4POdZpmcUt_DacVLT8-qwnq6NWpm8bqm_uUQu3JjqcHKLz7zWKopeLG_ZY7a45IqUQpwbMg9ICE1ZNTe5nsMHAJnevgLfWk14wnvVQyRVvlSvatdUTg0EjBc6P35a4lY12vIOq2ENpA-m52TfXeXxXK0vtZfT9SY33thi4EfZABWL_jQyiio6b6Akrh6_PgQ-bh2H2Fpu8Z3GImrbHodcbnqFpmKYlMLwxDHnKPxY7PpyyV8HsWfEjqVlAX56stAIIG4_owwzMZMcFwgucAP176TwjaXJqm9v2-DXisD2cNjyGlJ_rec670rv61thjiJF2uZrB9Z2zoQVYnc3Y9sJMMPPmunUcXpNVZWSsPlFDoPa1ABoFnRbP8rO-qbNGP5N7xY2DuPRYOp3CdyxeyDPmGBC2556FNeLRj-PhPAkd61fgXsQZyS9N2jHmFUIKbL8o-e3bQnqW7ebEn7zAjS_LQ2DtgIdIneUu84hh8AduoW9ky_aOpqvBUmdnHUwZHQiSSdeCPnEOssVBbuDd3gbcQf_VWvplwcjTTrJPsqqZpirjfVGPFUCVAz6kD0vhFcvTdQt6DGqys61xg_VOfj6wxpKsXuXDuqwaeb4KpGniHx-23nECgKG86N_1BBX8RRAvYnksxIIxIxgyrng-y44CV9FL_wGfP0Plx6JjSUFOL1gDZTc5NrAPoOztEo1FbJ2Lq8gqBR9Ku9Yza3aYANAJQvAraTXzA0t1j6qcmh-WtXeI1GE-8neOJtlRVbzT5RvPiRJZAVmu9Pg97wbLLQNPJoqIYp-c9mieGsDxAi75C2M1ArRnCa4kJJXrupgzQzzFefWyaRkIvC2MP9MwB_Z_NY3mp3opcNlT1TdKLr1sncLUkk3qJ0Pwyr-5dsKrC6aenapBHO7G0OnA0qTi8-Oy91VqJYYcVjcOUQaxNeMtnk-pLJL7j3MzqNiDkc-OfR19fcWvDmmd9Z8wtj20khL4mTDn7qTUo-PsVR7GnpqkImmEmE8sa4ZlPHa4_IcZGFbdcwp9xuOndINlzWGrIKywFPQ1x26zXDEa7fOx5f01aX8dIU_KWNAGdaZxPIlqLW5qbC6dipSqf9NwblZLJs5DCiLV8nHS-QM26xQJVUNH22n_3Z_8z1SA8AX8d7j0-g1Pf7NZC8e8Ipnm4B3YGpA7nn471aTbJb4OUamfgys17MV_hPDK_f7FF7NXp06-dtVYDmcs-87ZkrDuluOkUaRivKULwjEtSbiiKZAKirGfAOuwyCbbzygEpqYvEztABSmDYd_F_autklob_0deKuvvRYFpVCaxeaYQ7WIkpfBbMxeh9Qci7kPfgyB5H9ajWEJV3fgRk10Q1RaWyTUddQ_jWaluiDa3GD_t39sUrG7QhXc2Oz1NPPNoY6-A4jFbFCtXSF1muztqy0xaworcNiHY18yeL4Cw2iYLJ1Q3O4NnFo3E-wIXmYF4CLxZifr2Jkd6Ix1w-wlsN6vyCcDs8JeAgeJn0_Oahk1mgvRhVz8FFeidSdFqJBxGKbfZ32F_auJwrsLyjN_ShxTSFofyKQy2XCfoVMko4eu5o6md66xBmjZvTvItXL7f-eD0JxISBsBkZG3mFrApZKbdpI1lEa681ZbCxRTYpxUR7McTbs0Q5S9PCN5ElUz_axfeupIIbCTE4S0-ZQuIdQcQ2pn1j-4t2c04jtLE6WFI-1ASBCedlZmrZUiRegbezE01hMiFnfN32BhBu7ZcnlBCdWwj9hUfpEduJIgaA3acXhysGs40nqRzR9imvX9CBQYJZjrCHr-wORF6svmvF5FADRgwbM7Cc9puJgLBiQwXrhD43B6kjX_OXi5O2UNZFkAPr0WONBJsip8CgR6pt1u_mIKlIrYM9kM-idJGGT0DZ9UU4LMx0-9_2KCCkjDqgYN1rS9DA__GP9tS3dJ-XLSlk2URQuoHm4Xubv4vwgjUS7JzAxcQWHB0HtHFoZ3-tYVw_GRbRwyODm3E-N5O3L_R-pva9fvlPjkCNMrf2IlxAxBKML1gCxsSqhFr5yoPeW40LTxMF_dYPNLjC3l7mRRl_wfY_FhvayI7hrgCYfMgWeb-cXyx5eXumt9lMFOD3dQtEG1IUbdE7pVXG-barWK0Zl43DtQMNQzoCK_BLxfCsambyRRcI6E4QTfqe5lWtVf8Wi4KproenWyCjjzEjJQdWw4g-ae_bjGjfZCp38RgsXtWgI_tuzKyRF5WwjyN9VEoRXd8W2DctmBejHF2XDYzbMFkJ-384SokPX6intnlqBGMs0ssxriJhsFOA-vgDra6REx3DUMb8_u_Umc-zp4E6isX4D-eRYgElmj0ez945nqxp3YliO8mRLMW6E4OupLthfw4vmK3YqTAuXcnGxYrf7JqAkMfz5uAPi0SqPWDQZq7ycu9BmkMXAIhMb19XBDjL7hZGDwDRrn9yBBcYlPaFPNXjMJWJH_xxUKNsTFGg5-J_WdxXi8Zn6tDMxbxqqjIpw_FUaM00jJ2MhpbkzhEx7X85pBR47ScRgr6WJpf4ZLSFuV7NT1WI3PIBa_bYeCiq29fp3ShM-1bRFdJG_lGZd97TuAMF_QU6-KDXBv5i8kUZ1NXdJUz-YaA0RRVNFgMGM5n0pKB5IFncAPK-taTzHLIZJ9uuBdP2y2Hxwbw8YQlmy2-MT5XE5Ae_9kxuvIIlSzjpfLN9012HSnX4tZ8x3aWwof3E7s3jjzw7qbBtoUkYYpIGVOKf2EpmhEqevSlXYWpBYN3X2ZYjsrA9CL9PTvrPdyWLwKBmfh7cDJbjNXJSQLeKL7oHzicrllABzR9Ckkz7b24XGV1Klcat_Og4oB9qxiO2zJZWz2GDTAL0hosUlHLWnrQYvqFzzdIOzGlifwIyGgoRNb44IRMzzsErxuoqkdjZewVc4PzruHRlV3cWK6M7ZUiWLtxtMzas2sfAERy8BdS7ISLzj5PERoWyYXSW-898WD3ze5MJcpSsAYNEmPCBtdxF9l-Qz1LxuDa8hOCQ2Wzef1a2WFF5pCBaZRcAK_kef65xRst6WFpjWZGCLZUqHBhFDLEOd7Ikbw7d9V8dc4nAO65NQcxfT9JDUZadS2jmQJip8GLD4P9lGS1Ry-8rHCnMN7zXDp43TfyYhSgv9uj4xKi2wmAMMYBl0n2RNemx8nt-K_dknGgYYGOybDkg2uAUoXdxP33KfiRjbRpYqZVAiq0S45QLAIxxGiDJoZRnyIscdM6lryQtXj0PO67vRf6ifxC3wLv97HHUKergpXcAg-4_rNj_Zx_xiHMfCAe2q3DG1a_DcSmu5u1OPkBHmzHB9Vs8HV0E2-z44sl3Exqb5L8pMYpDnZ7QW-Qb1-S-zoESUy__AKhkRWPC7GmvmJJJHur6SRGSK0X2KyszkEYoe-8NhwpvLrYnNuVk7QknBS91KH2q8C0B8FKqcY40S5ILkImP9iOGIXYl5ZVRleoDBpH9BootWH2az5l7c_e-vfBGs7XpudoAq5wzhe_-AMBvKPCm0BoCX5B_NGUasXvEWobqUb61mpKCuVJdzVtexk-m8Jfvmdc8ooPJEYD_oosY5_S1LuHoc7GHLnoYdDVb2FhIPhOJCLQCef-Y3dtNThqOEo534Zg7R72nSeSQhdQ1hcBUsc50U2oF9OlOnV9z5hsfNwIxdUO9bdoXRYFmosmtpmDfGxAem0s5iPJ0EJ_8szlaX2pi6k6VP-ci-n7J8pEBwL2R3c-ei2iqB7JdLi7Gg6iXVMpQIFTxswh0HbgGtyZXgR_-AM91XRszm_kAlqAHTAJ7B-0Z5bJgMGEY2StBdhGzel_gNPVaxemC3DT0904GbCU2Z3avUHcedebI02_MdILdQxyXbw145KjqC15CqeaG--6x6WzpAuSjrFQRuz6Z5UyibW6Ay9R3P25c-gwmaRM8rPW5YkQtQdfzrtvGZ6wyhIcBXvbpU02OoChfRDF4xI2LvnaW3g6hQIUGe5lueI13ArYRAhZC0LHKPuVfv5OKeMqxYRtcN3YK6Ddc1t61rsA7MU1cAKzOGsiQ7aNyNBQHOV6z-W4-ws_DnZKYRMz0D_hwbeHO0ZKhciXng5VDCX4hyb47LExmO5N1mfihN3iHEkX_19rIgunfkSb9gd9B_AaazAttBEPPLtbsoZneQXBRl3PWiDpC_yXiLTWAd13AOBYHzBMKeJ4hplUqsAGTaGSztbpvV92wz_YX9kMEucHMu5hoM-TJbuWoheiiiKSFBNRK_g_rqXZo1UZjDOnHpHGJxOnlJBPp94Zvwh8sKLOpOd4qeOMLbnYKiag00al5x_3fBXq-KI0Y31OJfgDdCaKAQ0DUX71HN6XDOlvU1Iwh48iASJHdQGDmjhcS8YoeX9omwPiYhcbGJGzEVrn3H7h24eIf_7bVRpicMhjwghB0xtqTT0eVam1l8kr1-5kem7Dr2Kyqm2HpEwbi3KPXKYDXQRbHElEhazMCYr2wnjx_Bx2ai2uZa8uQyjN1zh1cjWHH0TicL2eAyc6YPKfKpmc5QwLrgT0ddQDhvXkCkN50fOR1Sbl56iFoAL8goFl3QA5wBk51vsDsquEt7nlz6sGTHzknENb-eEayrXnw-Q5FueFwqzoJpUrEYDXTxgOU8XVhrPv0Ot-BO6ORfzn3_1gREcHjhrc6RdF01NNqyzyVG0BdckywvAnzUGskWdCfP62dKdx46lAIRVPd3xG4tViaQ79GAeMVnqSeCLXbOyqfnJwhOT2fgQzLwxcj1tqGBBd3Pfx2d5-10WiL_mis0ven6golqaLq1EQsveb9AJpkYgJxdBeyHZXxNLMh4_XAuK1ZIs9F8Cz1vFEVcAFipev-cFyRvsdcNI2-HK2nOGkypEcuVATyLtA0jKeyPtE4TJ3_l8KXltEZjWycQAd_8Tj9is3wisC8bfzjll8UBjFZp-rzmCr8kA4cZih9gl27TiCmhyKhgMfDUIUmuDL_Rn9DLxEAT3Ebl1SW0ToCciNtKTH9oO-wnkPd-jg1HCooLcg-K_QkOTptJNZRFbXpooKqwH5Z9qsCxurZxnS_MscnE0qTa4EqrlpiDnj4FBs4q9SEPlKequfYzFmjQis1iwsReutf6pHmsvRmz9gx5vd6NMIkI05IeLNDElvlOGD04m1vR4ZISdmdHaAgaW9_AUPGx0vP1Rqe36cvebwUYSnzdbZ7y1s7PH7GXF5r7zNEzY9bHmXvsjb3N_u9BkenwkQfZGS6ez0AAAAAAAAAAALGSAlKzg7Qw',\n          },\n        ],\n      },\n      json_flat: {\n        payload: 'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',\n        protected:\n          'eyJhbGciOiJNTC1EU0EtODciLCJraWQiOiJ0Um4xSk5Ja2dNc0FCVlFCbFhlREh4QUljY2xoLTJJWDBVZERFelB0NVhVIn0',\n        signature:\n          'hmMrKkUgZwGPQV_WUoXUVq_Z9WOenDZbfMmHpKritl0btWi29TC8eIyQyT1FAuW2kg3h6ALsvCrjX5tn3QKFQZYC0sBdRt0VNiDm0BjyJ4jWcomSCgb0-cGXaLlODAz-njGridYfO1DpGMwHHshuKuvECv4qnX3XgZPE-6C8La43TZrYO8brzBXGiuyGMLq-TSmXavOeiadtpp6iTUqJDBgQSYvPB6PvipeCPlQH2ZQi8qkraxspi0lgy8Jh2aRYj44DX2ZKq-Ml-hfBJB4iHRpWmwPpEH7Ed4LkBIlaqZoPccrPgpGQpyz4_FcahrJc8CGGtTO5I34o5BcuZej7WOQvJ6mRmvYqIrYwoLs-3_YFZkVdX4KU38oprMvAHjObOhy_vZZArMnCgfYlCKrANbhOZG8O0BXgqow5Bqv_oRIztGQZMrivp_1CS0hELarwkwjdqyH5R747ndV26IQkeyn6y9daXRZIWxaC9KmAaDSm5-YsRVpiAAr0QmfaV51z065_r5qZmOMFIBERVi9Bbm_Z7ipJkoIL2SqVsePATfHeWB8huFpVFxdeEkJUPDuBtthax0HhxpRuECpFNJf2xA70Hp5C5VZIsi5EO21HuRpixiNKmXP5whhsn_uv_B7R4f4DX6X6A53lFrUfpFIrTfOQvBAvmEUUTSGcPeT-F7f_1lz34uFyN3ZT4FCeCh4n4yyZY1fSPVMNtOfK8GrLrRoWdi8gMk30oTKgb9zFkFU7uZhVEVRV86A_060bgFSHWDz5dlXLfyCoJsbsHlO9WBibTCkrMv6lnjh4czprro2prRtJAJB2jVwS1dv2mo4wP1lFYqY63yM9I9deU4fxy6mkwig7XwcVJskg8jX_0agATqmrKfYWMI4yGQ9fciYacgN8X2uSHqiPU1cgQ8VUGsSAsw4POdZpmcUt_DacVLT8-qwnq6NWpm8bqm_uUQu3JjqcHKLz7zWKopeLG_ZY7a45IqUQpwbMg9ICE1ZNTe5nsMHAJnevgLfWk14wnvVQyRVvlSvatdUTg0EjBc6P35a4lY12vIOq2ENpA-m52TfXeXxXK0vtZfT9SY33thi4EfZABWL_jQyiio6b6Akrh6_PgQ-bh2H2Fpu8Z3GImrbHodcbnqFpmKYlMLwxDHnKPxY7PpyyV8HsWfEjqVlAX56stAIIG4_owwzMZMcFwgucAP176TwjaXJqm9v2-DXisD2cNjyGlJ_rec670rv61thjiJF2uZrB9Z2zoQVYnc3Y9sJMMPPmunUcXpNVZWSsPlFDoPa1ABoFnRbP8rO-qbNGP5N7xY2DuPRYOp3CdyxeyDPmGBC2556FNeLRj-PhPAkd61fgXsQZyS9N2jHmFUIKbL8o-e3bQnqW7ebEn7zAjS_LQ2DtgIdIneUu84hh8AduoW9ky_aOpqvBUmdnHUwZHQiSSdeCPnEOssVBbuDd3gbcQf_VWvplwcjTTrJPsqqZpirjfVGPFUCVAz6kD0vhFcvTdQt6DGqys61xg_VOfj6wxpKsXuXDuqwaeb4KpGniHx-23nECgKG86N_1BBX8RRAvYnksxIIxIxgyrng-y44CV9FL_wGfP0Plx6JjSUFOL1gDZTc5NrAPoOztEo1FbJ2Lq8gqBR9Ku9Yza3aYANAJQvAraTXzA0t1j6qcmh-WtXeI1GE-8neOJtlRVbzT5RvPiRJZAVmu9Pg97wbLLQNPJoqIYp-c9mieGsDxAi75C2M1ArRnCa4kJJXrupgzQzzFefWyaRkIvC2MP9MwB_Z_NY3mp3opcNlT1TdKLr1sncLUkk3qJ0Pwyr-5dsKrC6aenapBHO7G0OnA0qTi8-Oy91VqJYYcVjcOUQaxNeMtnk-pLJL7j3MzqNiDkc-OfR19fcWvDmmd9Z8wtj20khL4mTDn7qTUo-PsVR7GnpqkImmEmE8sa4ZlPHa4_IcZGFbdcwp9xuOndINlzWGrIKywFPQ1x26zXDEa7fOx5f01aX8dIU_KWNAGdaZxPIlqLW5qbC6dipSqf9NwblZLJs5DCiLV8nHS-QM26xQJVUNH22n_3Z_8z1SA8AX8d7j0-g1Pf7NZC8e8Ipnm4B3YGpA7nn471aTbJb4OUamfgys17MV_hPDK_f7FF7NXp06-dtVYDmcs-87ZkrDuluOkUaRivKULwjEtSbiiKZAKirGfAOuwyCbbzygEpqYvEztABSmDYd_F_autklob_0deKuvvRYFpVCaxeaYQ7WIkpfBbMxeh9Qci7kPfgyB5H9ajWEJV3fgRk10Q1RaWyTUddQ_jWaluiDa3GD_t39sUrG7QhXc2Oz1NPPNoY6-A4jFbFCtXSF1muztqy0xaworcNiHY18yeL4Cw2iYLJ1Q3O4NnFo3E-wIXmYF4CLxZifr2Jkd6Ix1w-wlsN6vyCcDs8JeAgeJn0_Oahk1mgvRhVz8FFeidSdFqJBxGKbfZ32F_auJwrsLyjN_ShxTSFofyKQy2XCfoVMko4eu5o6md66xBmjZvTvItXL7f-eD0JxISBsBkZG3mFrApZKbdpI1lEa681ZbCxRTYpxUR7McTbs0Q5S9PCN5ElUz_axfeupIIbCTE4S0-ZQuIdQcQ2pn1j-4t2c04jtLE6WFI-1ASBCedlZmrZUiRegbezE01hMiFnfN32BhBu7ZcnlBCdWwj9hUfpEduJIgaA3acXhysGs40nqRzR9imvX9CBQYJZjrCHr-wORF6svmvF5FADRgwbM7Cc9puJgLBiQwXrhD43B6kjX_OXi5O2UNZFkAPr0WONBJsip8CgR6pt1u_mIKlIrYM9kM-idJGGT0DZ9UU4LMx0-9_2KCCkjDqgYN1rS9DA__GP9tS3dJ-XLSlk2URQuoHm4Xubv4vwgjUS7JzAxcQWHB0HtHFoZ3-tYVw_GRbRwyODm3E-N5O3L_R-pva9fvlPjkCNMrf2IlxAxBKML1gCxsSqhFr5yoPeW40LTxMF_dYPNLjC3l7mRRl_wfY_FhvayI7hrgCYfMgWeb-cXyx5eXumt9lMFOD3dQtEG1IUbdE7pVXG-barWK0Zl43DtQMNQzoCK_BLxfCsambyRRcI6E4QTfqe5lWtVf8Wi4KproenWyCjjzEjJQdWw4g-ae_bjGjfZCp38RgsXtWgI_tuzKyRF5WwjyN9VEoRXd8W2DctmBejHF2XDYzbMFkJ-384SokPX6intnlqBGMs0ssxriJhsFOA-vgDra6REx3DUMb8_u_Umc-zp4E6isX4D-eRYgElmj0ez945nqxp3YliO8mRLMW6E4OupLthfw4vmK3YqTAuXcnGxYrf7JqAkMfz5uAPi0SqPWDQZq7ycu9BmkMXAIhMb19XBDjL7hZGDwDRrn9yBBcYlPaFPNXjMJWJH_xxUKNsTFGg5-J_WdxXi8Zn6tDMxbxqqjIpw_FUaM00jJ2MhpbkzhEx7X85pBR47ScRgr6WJpf4ZLSFuV7NT1WI3PIBa_bYeCiq29fp3ShM-1bRFdJG_lGZd97TuAMF_QU6-KDXBv5i8kUZ1NXdJUz-YaA0RRVNFgMGM5n0pKB5IFncAPK-taTzHLIZJ9uuBdP2y2Hxwbw8YQlmy2-MT5XE5Ae_9kxuvIIlSzjpfLN9012HSnX4tZ8x3aWwof3E7s3jjzw7qbBtoUkYYpIGVOKf2EpmhEqevSlXYWpBYN3X2ZYjsrA9CL9PTvrPdyWLwKBmfh7cDJbjNXJSQLeKL7oHzicrllABzR9Ckkz7b24XGV1Klcat_Og4oB9qxiO2zJZWz2GDTAL0hosUlHLWnrQYvqFzzdIOzGlifwIyGgoRNb44IRMzzsErxuoqkdjZewVc4PzruHRlV3cWK6M7ZUiWLtxtMzas2sfAERy8BdS7ISLzj5PERoWyYXSW-898WD3ze5MJcpSsAYNEmPCBtdxF9l-Qz1LxuDa8hOCQ2Wzef1a2WFF5pCBaZRcAK_kef65xRst6WFpjWZGCLZUqHBhFDLEOd7Ikbw7d9V8dc4nAO65NQcxfT9JDUZadS2jmQJip8GLD4P9lGS1Ry-8rHCnMN7zXDp43TfyYhSgv9uj4xKi2wmAMMYBl0n2RNemx8nt-K_dknGgYYGOybDkg2uAUoXdxP33KfiRjbRpYqZVAiq0S45QLAIxxGiDJoZRnyIscdM6lryQtXj0PO67vRf6ifxC3wLv97HHUKergpXcAg-4_rNj_Zx_xiHMfCAe2q3DG1a_DcSmu5u1OPkBHmzHB9Vs8HV0E2-z44sl3Exqb5L8pMYpDnZ7QW-Qb1-S-zoESUy__AKhkRWPC7GmvmJJJHur6SRGSK0X2KyszkEYoe-8NhwpvLrYnNuVk7QknBS91KH2q8C0B8FKqcY40S5ILkImP9iOGIXYl5ZVRleoDBpH9BootWH2az5l7c_e-vfBGs7XpudoAq5wzhe_-AMBvKPCm0BoCX5B_NGUasXvEWobqUb61mpKCuVJdzVtexk-m8Jfvmdc8ooPJEYD_oosY5_S1LuHoc7GHLnoYdDVb2FhIPhOJCLQCef-Y3dtNThqOEo534Zg7R72nSeSQhdQ1hcBUsc50U2oF9OlOnV9z5hsfNwIxdUO9bdoXRYFmosmtpmDfGxAem0s5iPJ0EJ_8szlaX2pi6k6VP-ci-n7J8pEBwL2R3c-ei2iqB7JdLi7Gg6iXVMpQIFTxswh0HbgGtyZXgR_-AM91XRszm_kAlqAHTAJ7B-0Z5bJgMGEY2StBdhGzel_gNPVaxemC3DT0904GbCU2Z3avUHcedebI02_MdILdQxyXbw145KjqC15CqeaG--6x6WzpAuSjrFQRuz6Z5UyibW6Ay9R3P25c-gwmaRM8rPW5YkQtQdfzrtvGZ6wyhIcBXvbpU02OoChfRDF4xI2LvnaW3g6hQIUGe5lueI13ArYRAhZC0LHKPuVfv5OKeMqxYRtcN3YK6Ddc1t61rsA7MU1cAKzOGsiQ7aNyNBQHOV6z-W4-ws_DnZKYRMz0D_hwbeHO0ZKhciXng5VDCX4hyb47LExmO5N1mfihN3iHEkX_19rIgunfkSb9gd9B_AaazAttBEPPLtbsoZneQXBRl3PWiDpC_yXiLTWAd13AOBYHzBMKeJ4hplUqsAGTaGSztbpvV92wz_YX9kMEucHMu5hoM-TJbuWoheiiiKSFBNRK_g_rqXZo1UZjDOnHpHGJxOnlJBPp94Zvwh8sKLOpOd4qeOMLbnYKiag00al5x_3fBXq-KI0Y31OJfgDdCaKAQ0DUX71HN6XDOlvU1Iwh48iASJHdQGDmjhcS8YoeX9omwPiYhcbGJGzEVrn3H7h24eIf_7bVRpicMhjwghB0xtqTT0eVam1l8kr1-5kem7Dr2Kyqm2HpEwbi3KPXKYDXQRbHElEhazMCYr2wnjx_Bx2ai2uZa8uQyjN1zh1cjWHH0TicL2eAyc6YPKfKpmc5QwLrgT0ddQDhvXkCkN50fOR1Sbl56iFoAL8goFl3QA5wBk51vsDsquEt7nlz6sGTHzknENb-eEayrXnw-Q5FueFwqzoJpUrEYDXTxgOU8XVhrPv0Ot-BO6ORfzn3_1gREcHjhrc6RdF01NNqyzyVG0BdckywvAnzUGskWdCfP62dKdx46lAIRVPd3xG4tViaQ79GAeMVnqSeCLXbOyqfnJwhOT2fgQzLwxcj1tqGBBd3Pfx2d5-10WiL_mis0ven6golqaLq1EQsveb9AJpkYgJxdBeyHZXxNLMh4_XAuK1ZIs9F8Cz1vFEVcAFipev-cFyRvsdcNI2-HK2nOGkypEcuVATyLtA0jKeyPtE4TJ3_l8KXltEZjWycQAd_8Tj9is3wisC8bfzjll8UBjFZp-rzmCr8kA4cZih9gl27TiCmhyKhgMfDUIUmuDL_Rn9DLxEAT3Ebl1SW0ToCciNtKTH9oO-wnkPd-jg1HCooLcg-K_QkOTptJNZRFbXpooKqwH5Z9qsCxurZxnS_MscnE0qTa4EqrlpiDnj4FBs4q9SEPlKequfYzFmjQis1iwsReutf6pHmsvRmz9gx5vd6NMIkI05IeLNDElvlOGD04m1vR4ZISdmdHaAgaW9_AUPGx0vP1Rqe36cvebwUYSnzdbZ7y1s7PH7GXF5r7zNEzY9bHmXvsjb3N_u9BkenwkQfZGS6ez0AAAAAAAAAAALGSAlKzg7Qw',\n      },\n    },\n  },\n]\n"
  },
  {
    "path": "docs/README.md",
    "content": "# `jose` API Documentation\n\n`jose` is JavaScript module for JSON Object Signing and Encryption, providing support for JSON Web Tokens (JWT), JSON Web Signature (JWS), JSON Web Encryption (JWE), JSON Web Key (JWK), JSON Web Key Set (JWKS), and more. The module is designed to work across various Web-interoperable runtimes including Node.js, browsers, Cloudflare Workers, Deno, Bun, and others.\n\n## Sponsor\n\n<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"../sponsor/Auth0byOkta_dark.png\">\n  <source media=\"(prefers-color-scheme: light)\" srcset=\"../sponsor/Auth0byOkta_light.png\">\n  <img height=\"65\" align=\"left\" alt=\"Auth0 by Okta\" src=\"../sponsor/Auth0byOkta_light.png\">\n</picture>\n\nIf you want to quickly add JWT authentication to JavaScript apps, feel free to check out Auth0's JavaScript SDK and free plan. [Create an Auth0 account; it's free!][sponsor-auth0]<br><br>\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n## Available modules\n\n`jose` is distributed via [npmjs.com](https://www.npmjs.com/package/jose), [jsr.io](https://jsr.io/@panva/jose), [jsdelivr.com](https://www.jsdelivr.com/package/npm/jose), and [github.com](https://github.com/panva/jose).\n\n**`example`** ESM import[^cjs]\n\n```js\nimport * as jose from 'jose'\n```\n\n### JSON Web Tokens (JWT)\n\nThe `jose` module supports JSON Web Tokens (JWT) and provides functionality for signing and verifying tokens, as well as their JWT Claims Set validation.\n\n- [JWT Claims Set Validation & Signature Verification](jwt/verify/functions/jwtVerify.md) using the `jwtVerify` function\n  - [Using a remote JSON Web Key Set (JWKS)](jwks/remote/functions/createRemoteJWKSet.md)\n  - [Using a local JSON Web Key Set (JWKS)](jwks/local/functions/createLocalJWKSet.md)\n- [Signing](jwt/sign/classes/SignJWT.md) using the `SignJWT` class\n- Utility functions\n  - [Decoding Token's Protected Header](util/decode_protected_header/functions/decodeProtectedHeader.md)\n  - [Decoding JWT Claims Set](util/decode_jwt/functions/decodeJwt.md) prior to its validation\n\n### Encrypted JSON Web Tokens\n\nThe `jose` module supports encrypted JSON Web Tokens and provides functionality for encrypting and decrypting tokens, as well as their JWT Claims Set validation.\n\n- [Decryption & JWT Claims Set Validation](jwt/decrypt/functions/jwtDecrypt.md) using the `jwtDecrypt` function\n- [Encryption](jwt/encrypt/classes/EncryptJWT.md) using the `EncryptJWT` class\n- Utility functions\n  - [Decoding Token's Protected Header](util/decode_protected_header/functions/decodeProtectedHeader.md)\n\n### Key Utilities\n\nThe `jose` module supports importing, exporting, and generating keys and secrets in various formats, including PEM formats like SPKI, X.509 certificate, and PKCS #8, as well as JSON Web Key (JWK).\n\n- Key Import Functions\n  - [JWK Import](key/import/functions/importJWK.md)\n  - [Public Key Import (SPKI)](key/import/functions/importSPKI.md)\n  - [Public Key Import (X.509 Certificate)](key/import/functions/importX509.md)\n  - [Private Key Import (PKCS #8)](key/import/functions/importPKCS8.md)\n- Key and Secret Generation Functions\n  - [Asymmetric Key Pair Generation](key/generate_key_pair/functions/generateKeyPair.md)\n  - [Symmetric Secret Generation](key/generate_secret/functions/generateSecret.md)\n- Key Export Functions\n  - [JWK Export](key/export/functions/exportJWK.md)\n  - [Private Key Export](key/export/functions/exportPKCS8.md)\n  - [Public Key Export](key/export/functions/exportSPKI.md)\n\n### JSON Web Signature (JWS)\n\nThe `jose` module supports signing and verification of JWS messages with arbitrary payloads in Compact, Flattened JSON, and General JSON serialization syntaxes.\n\n- Signing - [Compact](jws/compact/sign/classes/CompactSign.md), [Flattened JSON](jws/flattened/sign/classes/FlattenedSign.md), [General JSON](jws/general/sign/classes/GeneralSign.md)\n- Verification - [Compact](jws/compact/verify/functions/compactVerify.md), [Flattened JSON](jws/flattened/verify/functions/flattenedVerify.md), [General JSON](jws/general/verify/functions/generalVerify.md)\n  - [Using a remote JSON Web Key Set (JWKS)](jwks/remote/functions/createRemoteJWKSet.md)\n  - [Using a local JSON Web Key Set (JWKS)](jwks/local/functions/createLocalJWKSet.md)\n- Utility functions\n  - [Decoding Token's Protected Header](util/decode_protected_header/functions/decodeProtectedHeader.md)\n\n### JSON Web Encryption (JWE)\n\nThe `jose` module supports encryption and decryption of JWE messages with arbitrary plaintext in Compact, Flattened JSON, and General JSON serialization syntaxes.\n\n- Encryption - [Compact](jwe/compact/encrypt/classes/CompactEncrypt.md), [Flattened JSON](jwe/flattened/encrypt/classes/FlattenedEncrypt.md), [General JSON](jwe/general/encrypt/classes/GeneralEncrypt.md)\n- Decryption - [Compact](jwe/compact/decrypt/functions/compactDecrypt.md), [Flattened JSON](jwe/flattened/decrypt/functions/flattenedDecrypt.md), [General JSON](jwe/general/decrypt/functions/generalDecrypt.md)\n- Utility functions\n  - [Decoding Token's Protected Header](util/decode_protected_header/functions/decodeProtectedHeader.md)\n\n### Other\n\nThe following are additional features and utilities provided by the `jose` module:\n\n- [Calculating JWK Thumbprint](jwk/thumbprint/functions/calculateJwkThumbprint.md)\n- [Calculating JWK Thumbprint URI](jwk/thumbprint/functions/calculateJwkThumbprintUri.md)\n- [Verification using a JWK Embedded in a JWS Header](jwk/embedded/functions/EmbeddedJWK.md)\n- [Unsecured JWT](jwt/unsecured/classes/UnsecuredJWT.md)\n- [JOSE Errors](util/errors/README.md)\n\n[sponsor-auth0]: https://a0.to/signup/panva\n\n[^cjs]: CJS style `let jose = require('jose')` is possible in Node.js versions where `process.features.require_module` is `true` or with the `--experimental-require-module` Node.js CLI flag.\n"
  },
  {
    "path": "docs/jwe/compact/decrypt/README.md",
    "content": "# jwe/compact/decrypt\n\nDecrypting JSON Web Encryption (JWE) in Compact Serialization\n\n## Interfaces\n\n- [CompactDecryptGetKey](interfaces/CompactDecryptGetKey.md)\n\n## Functions\n\n- [compactDecrypt](functions/compactDecrypt.md)\n"
  },
  {
    "path": "docs/jwe/compact/decrypt/functions/compactDecrypt.md",
    "content": "# Function: compactDecrypt()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n## Call Signature\n\n▸ **compactDecrypt**(`jwe`, `key`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CompactDecryptResult`](../../../../types/interfaces/CompactDecryptResult.md)\\>\n\nDecrypts a Compact JWE.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/jwe/compact/decrypt'`.\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwe` | `string` \\| [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | Compact JWE. |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) | Private Key or Secret to decrypt the JWE with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg). |\n| `options?` | [`DecryptOptions`](../../../../types/interfaces/DecryptOptions.md) | JWE Decryption options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CompactDecryptResult`](../../../../types/interfaces/CompactDecryptResult.md)\\>\n\n### Example\n\n```js\nconst jwe =\n  'eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0.nyQ19eq9ogh9wA7fFtnI2oouzy5_8b5DeLkoRMfi2yijgfTs2zEnayCEofz_qhnL-nwszabd9qUeHv0-IwvhhJJS7GUJOU3ikiIe42qcIAFme1A_Fo9CTxw4XTOy-I5qanl8So91u6hwfyN1VxAqVLsSE7_23EC-gfGEg_5znew9PyXXsOIE-K_HH7IQowRrlZ1X_bM_Liu53RzDpLDvRz59mp3S8L56YqpM8FexFGTGpEaoTcEIst375qncYt3-79IVR7gZN1RWsWgjPatfvVbnh74PglQcATSf3UUhaW0OAKn6q7r3PDx6DIKQ35bgHQg5QopuN00eIfLQL2trGw.W3grIVj5HVuAb76X.6PcuDe5D6ttWFYyv0oqqdDXfI2R8wBg1F2Q80UUA_Gv8eEimNWfxIWdLxrjzgQGSvIhxmFKuLM0.a93_Ug3uZHuczj70Zavx8Q'\n\nconst { plaintext, protectedHeader } = await jose.compactDecrypt(jwe, privateKey)\n\nconsole.log(protectedHeader)\nconsole.log(new TextDecoder().decode(plaintext))\n```\n\n## Call Signature\n\n▸ **compactDecrypt**(`jwe`, `getKey`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CompactDecryptResult`](../../../../types/interfaces/CompactDecryptResult.md) & [`ResolvedKey`](../../../../types/interfaces/ResolvedKey.md)\\>\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwe` | `string` \\| [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | Compact JWE. |\n| `getKey` | [`CompactDecryptGetKey`](../interfaces/CompactDecryptGetKey.md) | Function resolving Private Key or Secret to decrypt the JWE with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg). |\n| `options?` | [`DecryptOptions`](../../../../types/interfaces/DecryptOptions.md) | JWE Decryption options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CompactDecryptResult`](../../../../types/interfaces/CompactDecryptResult.md) & [`ResolvedKey`](../../../../types/interfaces/ResolvedKey.md)\\>\n"
  },
  {
    "path": "docs/jwe/compact/decrypt/interfaces/CompactDecryptGetKey.md",
    "content": "# Interface: CompactDecryptGetKey()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nInterface for Compact JWE Decryption dynamic key resolution. No token components have been\nverified at the time of this function call.\n\n▸ **CompactDecryptGetKey**(`protectedHeader`, `token`): [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md)\\>\n\nDynamic key resolution function. No token components have been verified at the time of this\nfunction call.\n\nIf a suitable key for the token cannot be matched, throw an error instead.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`CompactJWEHeaderParameters`](../../../../types/interfaces/CompactJWEHeaderParameters.md) | JWE or JWS Protected Header. |\n| `token` | [`FlattenedJWE`](../../../../types/interfaces/FlattenedJWE.md) | The consumed JWE or JWS token. |\n\n## Returns\n\n[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md)\\>\n"
  },
  {
    "path": "docs/jwe/compact/encrypt/README.md",
    "content": "# jwe/compact/encrypt\n\nEncrypting JSON Web Encryption (JWE) in Compact Serialization\n\n## Classes\n\n- [CompactEncrypt](classes/CompactEncrypt.md)\n"
  },
  {
    "path": "docs/jwe/compact/encrypt/classes/CompactEncrypt.md",
    "content": "# Class: CompactEncrypt\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nThe CompactEncrypt class is used to build and encrypt Compact JWE strings.\n\nThis class is exported (as a named export) from the main `'jose'` module entry point as well as\nfrom its subpath export `'jose/jwe/compact/encrypt'`.\n\n## Example\n\n```js\nconst jwe = await new jose.CompactEncrypt(\n  new TextEncoder().encode('It’s a dangerous business, Frodo, going out your door.'),\n)\n  .setProtectedHeader({ alg: 'RSA-OAEP-256', enc: 'A256GCM' })\n  .encrypt(publicKey)\n\nconsole.log(jwe)\n```\n\n## Constructors\n\n### Constructor\n\n▸ **new CompactEncrypt**(`plaintext`): `CompactEncrypt`\n\nCompactEncrypt constructor\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `plaintext` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | Binary representation of the plaintext to encrypt. |\n\n#### Returns\n\n`CompactEncrypt`\n\n## Methods\n\n### encrypt()\n\n▸ **encrypt**(`key`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n\nEncrypts and resolves the value of the Compact JWE string.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) | Public Key or Secret to encrypt the JWE with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg). |\n| `options?` | [`EncryptOptions`](../../../../types/interfaces/EncryptOptions.md) | JWE Encryption options. |\n\n#### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n\n***\n\n### ~~setContentEncryptionKey()~~\n\n▸ **setContentEncryptionKey**(`cek`): `this`\n\nSets a content encryption key to use, by default a random suitable one is generated for the JWE\nenc\" (Encryption Algorithm) Header Parameter.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `cek` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | JWE Content Encryption Key. |\n\n#### Returns\n\n`this`\n\n#### Deprecated\n\nYou should not use this method. It is only really intended for test and vector\n  validation purposes.\n\n***\n\n### ~~setInitializationVector()~~\n\n▸ **setInitializationVector**(`iv`): `this`\n\nSets the JWE Initialization Vector to use for content encryption, by default a random suitable\none is generated for the JWE enc\" (Encryption Algorithm) Header Parameter.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `iv` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | JWE Initialization Vector. |\n\n#### Returns\n\n`this`\n\n#### Deprecated\n\nYou should not use this method. It is only really intended for test and vector\n  validation purposes.\n\n***\n\n### setKeyManagementParameters()\n\n▸ **setKeyManagementParameters**(`parameters`): `this`\n\nSets the JWE Key Management parameters to be used when encrypting.\n\n(ECDH-ES) Use of this method is needed for ECDH based algorithms to set the \"apu\" (Agreement\nPartyUInfo) or \"apv\" (Agreement PartyVInfo) parameters.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `parameters` | [`JWEKeyManagementHeaderParameters`](../../../../types/interfaces/JWEKeyManagementHeaderParameters.md) | JWE Key Management parameters. |\n\n#### Returns\n\n`this`\n\n***\n\n### setProtectedHeader()\n\n▸ **setProtectedHeader**(`protectedHeader`): `this`\n\nSets the JWE Protected Header on the CompactEncrypt object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`CompactJWEHeaderParameters`](../../../../types/interfaces/CompactJWEHeaderParameters.md) | JWE Protected Header object. |\n\n#### Returns\n\n`this`\n"
  },
  {
    "path": "docs/jwe/flattened/decrypt/README.md",
    "content": "# jwe/flattened/decrypt\n\nDecrypting JSON Web Encryption (JWE) in Flattened JSON Serialization\n\n## Interfaces\n\n- [FlattenedDecryptGetKey](interfaces/FlattenedDecryptGetKey.md)\n\n## Functions\n\n- [flattenedDecrypt](functions/flattenedDecrypt.md)\n"
  },
  {
    "path": "docs/jwe/flattened/decrypt/functions/flattenedDecrypt.md",
    "content": "# Function: flattenedDecrypt()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n## Call Signature\n\n▸ **flattenedDecrypt**(`jwe`, `key`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`FlattenedDecryptResult`](../../../../types/interfaces/FlattenedDecryptResult.md)\\>\n\nDecrypts a Flattened JWE.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/jwe/flattened/decrypt'`.\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwe` | [`FlattenedJWE`](../../../../types/interfaces/FlattenedJWE.md) | Flattened JWE. |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) | Private Key or Secret to decrypt the JWE with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg). |\n| `options?` | [`DecryptOptions`](../../../../types/interfaces/DecryptOptions.md) | JWE Decryption options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`FlattenedDecryptResult`](../../../../types/interfaces/FlattenedDecryptResult.md)\\>\n\n### Example\n\n```js\nconst jwe = {\n  ciphertext: '9EzjFISUyoG-ifC2mSihfP0DPC80yeyrxhTzKt1C_VJBkxeBG0MI4Te61Pk45RAGubUvBpU9jm4',\n  iv: '8Fy7A_IuoX5VXG9s',\n  tag: 'W76IYV6arGRuDSaSyWrQNg',\n  encrypted_key:\n    'Z6eD4UK_yFb5ZoKvKkGAdqywEG_m0e4IYo0x8Vf30LAMJcsc-_zSgIeiF82teZyYi2YYduHKoqImk7MRnoPZOlEs0Q5BNK1OgBmSOhCE8DFyqh9Zh48TCTP6lmBQ52naqoUJFMtHzu-0LwZH26hxos0GP3Dt19O379MJB837TdKKa87skq0zHaVLAquRHOBF77GI54Bc7O49d8aOrSu1VEFGMThlW2caspPRiTSePDMDPq7_WGk50izRhB3Asl9wmP9wEeaTrkJKRnQj5ips1SAZ1hDBsqEQKKukxP1HtdcopHV5_qgwU8Hjm5EwSLMluMQuiE6hwlkXGOujZLVizA',\n  aad: 'VGhlIEZlbGxvd3NoaXAgb2YgdGhlIFJpbmc',\n  protected: 'eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0',\n}\n\nconst { plaintext, protectedHeader, additionalAuthenticatedData } =\n  await jose.flattenedDecrypt(jwe, privateKey)\n\nconsole.log(protectedHeader)\nconst decoder = new TextDecoder()\nconsole.log(decoder.decode(plaintext))\nconsole.log(decoder.decode(additionalAuthenticatedData))\n```\n\n## Call Signature\n\n▸ **flattenedDecrypt**(`jwe`, `getKey`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`FlattenedDecryptResult`](../../../../types/interfaces/FlattenedDecryptResult.md) & [`ResolvedKey`](../../../../types/interfaces/ResolvedKey.md)\\>\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwe` | [`FlattenedJWE`](../../../../types/interfaces/FlattenedJWE.md) | Flattened JWE. |\n| `getKey` | [`FlattenedDecryptGetKey`](../interfaces/FlattenedDecryptGetKey.md) | Function resolving Private Key or Secret to decrypt the JWE with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg). |\n| `options?` | [`DecryptOptions`](../../../../types/interfaces/DecryptOptions.md) | JWE Decryption options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`FlattenedDecryptResult`](../../../../types/interfaces/FlattenedDecryptResult.md) & [`ResolvedKey`](../../../../types/interfaces/ResolvedKey.md)\\>\n"
  },
  {
    "path": "docs/jwe/flattened/decrypt/interfaces/FlattenedDecryptGetKey.md",
    "content": "# Interface: FlattenedDecryptGetKey()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nInterface for Flattened JWE Decryption dynamic key resolution. No token components have been\nverified at the time of this function call.\n\n▸ **FlattenedDecryptGetKey**(`protectedHeader`, `token`): [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md)\\>\n\nDynamic key resolution function. No token components have been verified at the time of this\nfunction call.\n\nIf a suitable key for the token cannot be matched, throw an error instead.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`JWEHeaderParameters`](../../../../types/interfaces/JWEHeaderParameters.md) \\| `undefined` | JWE or JWS Protected Header. |\n| `token` | [`FlattenedJWE`](../../../../types/interfaces/FlattenedJWE.md) | The consumed JWE or JWS token. |\n\n## Returns\n\n[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md)\\>\n"
  },
  {
    "path": "docs/jwe/flattened/encrypt/README.md",
    "content": "# jwe/flattened/encrypt\n\nEncrypting JSON Web Encryption (JWE) in Flattened JSON Serialization\n\n## Classes\n\n- [FlattenedEncrypt](classes/FlattenedEncrypt.md)\n"
  },
  {
    "path": "docs/jwe/flattened/encrypt/classes/FlattenedEncrypt.md",
    "content": "# Class: FlattenedEncrypt\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nThe FlattenedEncrypt class is used to build and encrypt Flattened JWE objects.\n\nThis class is exported (as a named export) from the main `'jose'` module entry point as well as\nfrom its subpath export `'jose/jwe/flattened/encrypt'`.\n\n## Example\n\n```js\nconst jwe = await new jose.FlattenedEncrypt(\n  new TextEncoder().encode('It’s a dangerous business, Frodo, going out your door.'),\n)\n  .setProtectedHeader({ alg: 'RSA-OAEP-256', enc: 'A256GCM' })\n  .setAdditionalAuthenticatedData(encoder.encode('The Fellowship of the Ring'))\n  .encrypt(publicKey)\n\nconsole.log(jwe)\n```\n\n## Constructors\n\n### Constructor\n\n▸ **new FlattenedEncrypt**(`plaintext`): `FlattenedEncrypt`\n\nFlattenedEncrypt constructor\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `plaintext` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | Binary representation of the plaintext to encrypt. |\n\n#### Returns\n\n`FlattenedEncrypt`\n\n## Methods\n\n### encrypt()\n\n▸ **encrypt**(`key`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`FlattenedJWE`](../../../../types/interfaces/FlattenedJWE.md)\\>\n\nEncrypts and resolves the value of the Flattened JWE object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) | Public Key or Secret to encrypt the JWE with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg). |\n| `options?` | [`EncryptOptions`](../../../../types/interfaces/EncryptOptions.md) | JWE Encryption options. |\n\n#### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`FlattenedJWE`](../../../../types/interfaces/FlattenedJWE.md)\\>\n\n***\n\n### setAdditionalAuthenticatedData()\n\n▸ **setAdditionalAuthenticatedData**(`aad`): `this`\n\nSets the Additional Authenticated Data on the FlattenedEncrypt object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `aad` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | Additional Authenticated Data. |\n\n#### Returns\n\n`this`\n\n***\n\n### ~~setContentEncryptionKey()~~\n\n▸ **setContentEncryptionKey**(`cek`): `this`\n\nSets a content encryption key to use, by default a random suitable one is generated for the JWE\nenc\" (Encryption Algorithm) Header Parameter.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `cek` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | JWE Content Encryption Key. |\n\n#### Returns\n\n`this`\n\n#### Deprecated\n\nYou should not use this method. It is only really intended for test and vector\n  validation purposes.\n\n***\n\n### ~~setInitializationVector()~~\n\n▸ **setInitializationVector**(`iv`): `this`\n\nSets the JWE Initialization Vector to use for content encryption, by default a random suitable\none is generated for the JWE enc\" (Encryption Algorithm) Header Parameter.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `iv` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | JWE Initialization Vector. |\n\n#### Returns\n\n`this`\n\n#### Deprecated\n\nYou should not use this method. It is only really intended for test and vector\n  validation purposes.\n\n***\n\n### setKeyManagementParameters()\n\n▸ **setKeyManagementParameters**(`parameters`): `this`\n\nSets the JWE Key Management parameters to be used when encrypting.\n\n(ECDH-ES) Use of this method is needed for ECDH based algorithms to set the \"apu\" (Agreement\nPartyUInfo) or \"apv\" (Agreement PartyVInfo) parameters.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `parameters` | [`JWEKeyManagementHeaderParameters`](../../../../types/interfaces/JWEKeyManagementHeaderParameters.md) | JWE Key Management parameters. |\n\n#### Returns\n\n`this`\n\n***\n\n### setProtectedHeader()\n\n▸ **setProtectedHeader**(`protectedHeader`): `this`\n\nSets the JWE Protected Header on the FlattenedEncrypt object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`JWEHeaderParameters`](../../../../types/interfaces/JWEHeaderParameters.md) | JWE Protected Header. |\n\n#### Returns\n\n`this`\n\n***\n\n### setSharedUnprotectedHeader()\n\n▸ **setSharedUnprotectedHeader**(`sharedUnprotectedHeader`): `this`\n\nSets the JWE Shared Unprotected Header on the FlattenedEncrypt object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `sharedUnprotectedHeader` | [`JWEHeaderParameters`](../../../../types/interfaces/JWEHeaderParameters.md) | JWE Shared Unprotected Header. |\n\n#### Returns\n\n`this`\n\n***\n\n### setUnprotectedHeader()\n\n▸ **setUnprotectedHeader**(`unprotectedHeader`): `this`\n\nSets the JWE Per-Recipient Unprotected Header on the FlattenedEncrypt object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `unprotectedHeader` | [`JWEHeaderParameters`](../../../../types/interfaces/JWEHeaderParameters.md) | JWE Per-Recipient Unprotected Header. |\n\n#### Returns\n\n`this`\n"
  },
  {
    "path": "docs/jwe/general/decrypt/README.md",
    "content": "# jwe/general/decrypt\n\nDecrypting JSON Web Encryption (JWE) in General JSON Serialization\n\n## Interfaces\n\n- [GeneralDecryptGetKey](interfaces/GeneralDecryptGetKey.md)\n\n## Functions\n\n- [generalDecrypt](functions/generalDecrypt.md)\n"
  },
  {
    "path": "docs/jwe/general/decrypt/functions/generalDecrypt.md",
    "content": "# Function: generalDecrypt()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n## Call Signature\n\n▸ **generalDecrypt**(`jwe`, `key`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralDecryptResult`](../../../../types/interfaces/GeneralDecryptResult.md)\\>\n\nDecrypts a General JWE.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/jwe/general/decrypt'`.\n\n> [!NOTE]\\\n> The function iterates over the `recipients` array in the General JWE and returns the decryption\n> result of the first recipient entry that can be successfully decrypted. The result only contains\n> the plaintext and headers of that successfully decrypted recipient entry. Other recipient entries\n> in the General JWE are not validated, and their headers are not included in the returned result.\n> Recipients of a General JWE should only rely on the returned (decrypted) data.\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwe` | [`GeneralJWE`](../../../../types/interfaces/GeneralJWE.md) | General JWE. |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) | Private Key or Secret to decrypt the JWE with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg). |\n| `options?` | [`DecryptOptions`](../../../../types/interfaces/DecryptOptions.md) | JWE Decryption options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralDecryptResult`](../../../../types/interfaces/GeneralDecryptResult.md)\\>\n\n### Example\n\n```js\nconst jwe = {\n  ciphertext: '9EzjFISUyoG-ifC2mSihfP0DPC80yeyrxhTzKt1C_VJBkxeBG0MI4Te61Pk45RAGubUvBpU9jm4',\n  iv: '8Fy7A_IuoX5VXG9s',\n  tag: 'W76IYV6arGRuDSaSyWrQNg',\n  aad: 'VGhlIEZlbGxvd3NoaXAgb2YgdGhlIFJpbmc',\n  protected: 'eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0',\n  recipients: [\n    {\n      encrypted_key:\n        'Z6eD4UK_yFb5ZoKvKkGAdqywEG_m0e4IYo0x8Vf30LAMJcsc-_zSgIeiF82teZyYi2YYduHKoqImk7MRnoPZOlEs0Q5BNK1OgBmSOhCE8DFyqh9Zh48TCTP6lmBQ52naqoUJFMtHzu-0LwZH26hxos0GP3Dt19O379MJB837TdKKa87skq0zHaVLAquRHOBF77GI54Bc7O49d8aOrSu1VEFGMThlW2caspPRiTSePDMDPq7_WGk50izRhB3Asl9wmP9wEeaTrkJKRnQj5ips1SAZ1hDBsqEQKKukxP1HtdcopHV5_qgwU8Hjm5EwSLMluMQuiE6hwlkXGOujZLVizA',\n    },\n  ],\n}\n\nconst { plaintext, protectedHeader, additionalAuthenticatedData } =\n  await jose.generalDecrypt(jwe, privateKey)\n\nconsole.log(protectedHeader)\nconst decoder = new TextDecoder()\nconsole.log(decoder.decode(plaintext))\nconsole.log(decoder.decode(additionalAuthenticatedData))\n```\n\n## Call Signature\n\n▸ **generalDecrypt**(`jwe`, `getKey`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralDecryptResult`](../../../../types/interfaces/GeneralDecryptResult.md) & [`ResolvedKey`](../../../../types/interfaces/ResolvedKey.md)\\>\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwe` | [`GeneralJWE`](../../../../types/interfaces/GeneralJWE.md) | General JWE. |\n| `getKey` | [`GeneralDecryptGetKey`](../interfaces/GeneralDecryptGetKey.md) | Function resolving Private Key or Secret to decrypt the JWE with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg). |\n| `options?` | [`DecryptOptions`](../../../../types/interfaces/DecryptOptions.md) | JWE Decryption options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralDecryptResult`](../../../../types/interfaces/GeneralDecryptResult.md) & [`ResolvedKey`](../../../../types/interfaces/ResolvedKey.md)\\>\n"
  },
  {
    "path": "docs/jwe/general/decrypt/interfaces/GeneralDecryptGetKey.md",
    "content": "# Interface: GeneralDecryptGetKey()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nInterface for General JWE Decryption dynamic key resolution. No token components have been\nverified at the time of this function call.\n\n▸ **GeneralDecryptGetKey**(`protectedHeader`, `token`): [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md)\\>\n\nDynamic key resolution function. No token components have been verified at the time of this\nfunction call.\n\nIf a suitable key for the token cannot be matched, throw an error instead.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`JWEHeaderParameters`](../../../../types/interfaces/JWEHeaderParameters.md) | JWE or JWS Protected Header. |\n| `token` | [`FlattenedJWE`](../../../../types/interfaces/FlattenedJWE.md) | The consumed JWE or JWS token. |\n\n## Returns\n\n[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md)\\>\n"
  },
  {
    "path": "docs/jwe/general/encrypt/README.md",
    "content": "# jwe/general/encrypt\n\nEncrypting JSON Web Encryption (JWE) in General JSON Serialization\n\n## Classes\n\n- [GeneralEncrypt](classes/GeneralEncrypt.md)\n\n## Interfaces\n\n- [Recipient](interfaces/Recipient.md)\n"
  },
  {
    "path": "docs/jwe/general/encrypt/classes/GeneralEncrypt.md",
    "content": "# Class: GeneralEncrypt\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nThe GeneralEncrypt class is used to build and encrypt General JWE objects.\n\nThis class is exported (as a named export) from the main `'jose'` module entry point as well as\nfrom its subpath export `'jose/jwe/general/encrypt'`.\n\n## Example\n\n```js\nconst jwe = await new jose.GeneralEncrypt(\n  new TextEncoder().encode('It’s a dangerous business, Frodo, going out your door.'),\n)\n  .setProtectedHeader({ enc: 'A256GCM' })\n  .addRecipient(ecPublicKey)\n  .setUnprotectedHeader({ alg: 'ECDH-ES+A256KW' })\n  .addRecipient(rsaPublicKey)\n  .setUnprotectedHeader({ alg: 'RSA-OAEP-384' })\n  .encrypt()\n\nconsole.log(jwe)\n```\n\n## Constructors\n\n### Constructor\n\n▸ **new GeneralEncrypt**(`plaintext`): `GeneralEncrypt`\n\nGeneralEncrypt constructor\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `plaintext` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | Binary representation of the plaintext to encrypt. |\n\n#### Returns\n\n`GeneralEncrypt`\n\n## Methods\n\n### addRecipient()\n\n▸ **addRecipient**(`key`, `options?`): [`Recipient`](../interfaces/Recipient.md)\n\nAdds an additional recipient for the General JWE object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) | Public Key or Secret to encrypt the Content Encryption Key for the recipient with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg). |\n| `options?` | [`CritOption`](../../../../types/interfaces/CritOption.md) | JWE Encryption options. |\n\n#### Returns\n\n[`Recipient`](../interfaces/Recipient.md)\n\n***\n\n### encrypt()\n\n▸ **encrypt**(): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralJWE`](../../../../types/interfaces/GeneralJWE.md)\\>\n\nEncrypts and resolves the value of the General JWE object.\n\n#### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralJWE`](../../../../types/interfaces/GeneralJWE.md)\\>\n\n***\n\n### setAdditionalAuthenticatedData()\n\n▸ **setAdditionalAuthenticatedData**(`aad`): `this`\n\nSets the Additional Authenticated Data on the GeneralEncrypt object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `aad` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | Additional Authenticated Data. |\n\n#### Returns\n\n`this`\n\n***\n\n### setProtectedHeader()\n\n▸ **setProtectedHeader**(`protectedHeader`): `this`\n\nSets the JWE Protected Header on the GeneralEncrypt object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`JWEHeaderParameters`](../../../../types/interfaces/JWEHeaderParameters.md) | JWE Protected Header object. |\n\n#### Returns\n\n`this`\n\n***\n\n### setSharedUnprotectedHeader()\n\n▸ **setSharedUnprotectedHeader**(`sharedUnprotectedHeader`): `this`\n\nSets the JWE Shared Unprotected Header on the GeneralEncrypt object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `sharedUnprotectedHeader` | [`JWEHeaderParameters`](../../../../types/interfaces/JWEHeaderParameters.md) | JWE Shared Unprotected Header object. |\n\n#### Returns\n\n`this`\n"
  },
  {
    "path": "docs/jwe/general/encrypt/interfaces/Recipient.md",
    "content": "# Interface: Recipient\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nUsed to build General JWE object's individual recipients.\n\n## Methods\n\n### addRecipient()\n\n▸ **addRecipient**(...`args`): `Recipient`\n\nA shorthand for calling addRecipient() on the enclosing [GeneralEncrypt](../classes/GeneralEncrypt.md) instance\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| ...`args` | \\[[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md), [`CritOption`](../../../../types/interfaces/CritOption.md)\\] |\n\n#### Returns\n\n`Recipient`\n\n***\n\n### done()\n\n▸ **done**(): [`GeneralEncrypt`](../classes/GeneralEncrypt.md)\n\nReturns the enclosing [GeneralEncrypt](../classes/GeneralEncrypt.md) instance\n\n#### Returns\n\n[`GeneralEncrypt`](../classes/GeneralEncrypt.md)\n\n***\n\n### encrypt()\n\n▸ **encrypt**(...`args`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralJWE`](../../../../types/interfaces/GeneralJWE.md)\\>\n\nA shorthand for calling encrypt() on the enclosing [GeneralEncrypt](../classes/GeneralEncrypt.md) instance\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| ...`args` | \\[\\] |\n\n#### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralJWE`](../../../../types/interfaces/GeneralJWE.md)\\>\n\n***\n\n### setKeyManagementParameters()\n\n▸ **setKeyManagementParameters**(`parameters`): `Recipient`\n\nSets the JWE Key Management parameters to be used when encrypting.\n\n(ECDH-ES) Use of this method is needed for ECDH based algorithms to set the \"apu\" (Agreement\nPartyUInfo) or \"apv\" (Agreement PartyVInfo) parameters.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `parameters` | [`JWEKeyManagementHeaderParameters`](../../../../types/interfaces/JWEKeyManagementHeaderParameters.md) | JWE Key Management parameters. |\n\n#### Returns\n\n`Recipient`\n\n***\n\n### setUnprotectedHeader()\n\n▸ **setUnprotectedHeader**(`unprotectedHeader`): `Recipient`\n\nSets the JWE Per-Recipient Unprotected Header on the Recipient object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `unprotectedHeader` | [`JWEHeaderParameters`](../../../../types/interfaces/JWEHeaderParameters.md) | JWE Per-Recipient Unprotected Header. |\n\n#### Returns\n\n`Recipient`\n"
  },
  {
    "path": "docs/jwk/embedded/README.md",
    "content": "# jwk/embedded\n\nVerification using a JWK Embedded in a JWS Header\n\n## Functions\n\n- [EmbeddedJWK](functions/EmbeddedJWK.md)\n"
  },
  {
    "path": "docs/jwk/embedded/functions/EmbeddedJWK.md",
    "content": "# Function: EmbeddedJWK()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **EmbeddedJWK**(`protectedHeader?`, `token?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\nEmbeddedJWK is an implementation of a GetKeyFunction intended to be used with the JWS/JWT verify\noperations whenever you need to opt-in to verify signatures with a public key embedded in the\ntoken's \"jwk\" (JSON Web Key) Header Parameter. It is recommended to combine this with the verify\nfunction's `algorithms` option to define accepted JWS \"alg\" (Algorithm) Header Parameter values.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/jwk/embedded'`.\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `protectedHeader?` | [`JWSHeaderParameters`](../../../types/interfaces/JWSHeaderParameters.md) |\n| `token?` | [`FlattenedJWSInput`](../../../types/interfaces/FlattenedJWSInput.md) |\n\n## Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\n## Example\n\n```js\nconst jwt =\n  'eyJqd2siOnsiY3J2IjoiUC0yNTYiLCJ4IjoiVU05ZzVuS25aWFlvdldBbE03NmNMejl2VG96UmpfX0NIVV9kT2wtZ09vRSIsInkiOiJkczhhZVF3MWwyY0RDQTdiQ2tPTnZ3REtwWEFidFhqdnFDbGVZSDhXc19VIiwia3R5IjoiRUMifSwiYWxnIjoiRVMyNTYifQ.eyJpc3MiOiJ1cm46ZXhhbXBsZTppc3N1ZXIiLCJhdWQiOiJ1cm46ZXhhbXBsZTphdWRpZW5jZSIsImlhdCI6MTYwNDU4MDc5NH0.60boak3_dErnW47ZPty1C0nrjeVq86EN_eK0GOq6K8w2OA0thKoBxFK4j-NuU9yZ_A9UKGxPT_G87DladBaV9g'\n\nconst { payload, protectedHeader } = await jose.jwtVerify(jwt, jose.EmbeddedJWK, {\n  issuer: 'urn:example:issuer',\n  audience: 'urn:example:audience',\n})\n\nconsole.log(protectedHeader)\nconsole.log(payload)\n```\n"
  },
  {
    "path": "docs/jwk/thumbprint/README.md",
    "content": "# jwk/thumbprint\n\nJSON Web Key Thumbprint and JSON Web Key Thumbprint URI\n\n## Functions\n\n- [calculateJwkThumbprint](functions/calculateJwkThumbprint.md)\n- [calculateJwkThumbprintUri](functions/calculateJwkThumbprintUri.md)\n"
  },
  {
    "path": "docs/jwk/thumbprint/functions/calculateJwkThumbprint.md",
    "content": "# Function: calculateJwkThumbprint()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **calculateJwkThumbprint**(`key`, `digestAlgorithm?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n\nCalculates a base64url-encoded JSON Web Key (JWK) Thumbprint\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/jwk/thumbprint'`.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `key` | [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md) | Key to calculate the thumbprint for. |\n| `digestAlgorithm?` | `\"sha256\"` \\| `\"sha384\"` \\| `\"sha512\"` | Digest Algorithm to use for calculating the thumbprint. Default is \"sha256\". |\n\n## Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n\n## Example\n\n```js\nconst thumbprint = await jose.calculateJwkThumbprint({\n  kty: 'EC',\n  crv: 'P-256',\n  x: 'jJ6Flys3zK9jUhnOHf6G49Dyp5hah6CNP84-gY-n9eo',\n  y: 'nhI6iD5eFXgBTLt_1p3aip-5VbZeMhxeFSpjfEAf7Ww',\n})\n\nconsole.log(thumbprint)\n// 'w9eYdC6_s_tLQ8lH6PUpc0mddazaqtPgeC2IgWDiqY8'\n```\n\n## See\n\n[RFC7638](https://www.rfc-editor.org/rfc/rfc7638)\n"
  },
  {
    "path": "docs/jwk/thumbprint/functions/calculateJwkThumbprintUri.md",
    "content": "# Function: calculateJwkThumbprintUri()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **calculateJwkThumbprintUri**(`key`, `digestAlgorithm?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n\nCalculates a JSON Web Key (JWK) Thumbprint URI\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/jwk/thumbprint'`.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `key` | [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md) | Key to calculate the thumbprint for. |\n| `digestAlgorithm?` | `\"sha256\"` \\| `\"sha384\"` \\| `\"sha512\"` | Digest Algorithm to use for calculating the thumbprint. Default is \"sha256\". |\n\n## Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n\n## Example\n\n```js\nconst thumbprintUri = await jose.calculateJwkThumbprintUri({\n  kty: 'EC',\n  crv: 'P-256',\n  x: 'jJ6Flys3zK9jUhnOHf6G49Dyp5hah6CNP84-gY-n9eo',\n  y: 'nhI6iD5eFXgBTLt_1p3aip-5VbZeMhxeFSpjfEAf7Ww',\n})\n\nconsole.log(thumbprintUri)\n// 'urn:ietf:params:oauth:jwk-thumbprint:sha-256:w9eYdC6_s_tLQ8lH6PUpc0mddazaqtPgeC2IgWDiqY8'\n```\n\n## See\n\n[RFC9278](https://www.rfc-editor.org/rfc/rfc9278)\n"
  },
  {
    "path": "docs/jwks/local/README.md",
    "content": "# jwks/local\n\nVerification using a JSON Web Key Set (JWKS) available locally\n\n## Functions\n\n- [createLocalJWKSet](functions/createLocalJWKSet.md)\n"
  },
  {
    "path": "docs/jwks/local/functions/createLocalJWKSet.md",
    "content": "# Function: createLocalJWKSet()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **createLocalJWKSet**(`jwks`): (`protectedHeader?`, `token?`) => [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\nReturns a function that resolves a JWS JOSE Header to a public key object from a locally stored,\nor otherwise available, JSON Web Key Set.\n\nIt uses the \"alg\" (JWS Algorithm) Header Parameter to determine the right JWK \"kty\" (Key Type),\nthen proceeds to match the JWK \"kid\" (Key ID) with one found in the JWS Header Parameters (if\nthere is one) while also respecting the JWK \"use\" (Public Key Use) and JWK \"key_ops\" (Key\nOperations) Parameters (if they are present on the JWK).\n\nOnly a single public key must match the selection process. As shown in the example below when\nmultiple keys get matched it is possible to opt-in to iterate over the matched keys and attempt\nverification in an iterative manner.\n\n> [!NOTE]\\\n> The function's purpose is to resolve public keys used for verifying signatures and will not work\n> for public encryption keys.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/jwks/local'`.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwks` | [`JSONWebKeySet`](../../../types/interfaces/JSONWebKeySet.md) | JSON Web Key Set formatted object. |\n\n## Returns\n\n(`protectedHeader?`, `token?`) => [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\n## Examples\n\n```js\nconst JWKS = jose.createLocalJWKSet({\n  keys: [\n    {\n      kty: 'RSA',\n      e: 'AQAB',\n      n: '12oBZRhCiZFJLcPg59LkZZ9mdhSMTKAQZYq32k_ti5SBB6jerkh-WzOMAO664r_qyLkqHUSp3u5SbXtseZEpN3XPWGKSxjsy-1JyEFTdLSYe6f9gfrmxkUF_7DTpq0gn6rntP05g2-wFW50YO7mosfdslfrTJYWHFhJALabAeYirYD7-9kqq9ebfFMF4sRRELbv9oi36As6Q9B3Qb5_C1rAzqfao_PCsf9EPsTZsVVVkA5qoIAr47lo1ipfiBPxUCCNSdvkmDTYgvvRm6ZoMjFbvOtgyts55fXKdMWv7I9HMD5HwE9uW839PWA514qhbcIsXEYSFMPMV6fnlsiZvQQ',\n      alg: 'PS256',\n    },\n    {\n      crv: 'P-256',\n      kty: 'EC',\n      x: 'ySK38C1jBdLwDsNWKzzBHqKYEE5Cgv-qjWvorUXk9fw',\n      y: '_LeQBw07cf5t57Iavn4j-BqJsAD1dpoz8gokd3sBsOo',\n      alg: 'ES256',\n    },\n  ],\n})\n\nconst { payload, protectedHeader } = await jose.jwtVerify(jwt, JWKS, {\n  issuer: 'urn:example:issuer',\n  audience: 'urn:example:audience',\n})\nconsole.log(protectedHeader)\nconsole.log(payload)\n```\n\nOpting-in to multiple JWKS matches using `createLocalJWKSet`\n\n```js\nconst options = {\n  issuer: 'urn:example:issuer',\n  audience: 'urn:example:audience',\n}\nconst { payload, protectedHeader } = await jose\n  .jwtVerify(jwt, JWKS, options)\n  .catch(async (error) => {\n    if (error?.code === 'ERR_JWKS_MULTIPLE_MATCHING_KEYS') {\n      for await (const publicKey of error) {\n        try {\n          return await jose.jwtVerify(jwt, publicKey, options)\n        } catch (innerError) {\n          if (innerError?.code === 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') {\n            continue\n          }\n          throw innerError\n        }\n      }\n      throw new jose.errors.JWSSignatureVerificationFailed()\n    }\n\n    throw error\n  })\nconsole.log(protectedHeader)\nconsole.log(payload)\n```\n"
  },
  {
    "path": "docs/jwks/remote/README.md",
    "content": "# jwks/remote\n\nVerification using a JSON Web Key Set (JWKS) available on an HTTP(S) URL\n\n## Interfaces\n\n- [ExportedJWKSCache](interfaces/ExportedJWKSCache.md)\n- [RemoteJWKSetOptions](interfaces/RemoteJWKSetOptions.md)\n\n## Type Aliases\n\n- [FetchImplementation](type-aliases/FetchImplementation.md)\n- [JWKSCacheInput](type-aliases/JWKSCacheInput.md)\n\n## Variables\n\n- [customFetch](variables/customFetch.md)\n- [jwksCache](variables/jwksCache.md)\n\n## Functions\n\n- [createRemoteJWKSet](functions/createRemoteJWKSet.md)\n"
  },
  {
    "path": "docs/jwks/remote/functions/createRemoteJWKSet.md",
    "content": "# Function: createRemoteJWKSet()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **createRemoteJWKSet**(`url`, `options?`): (`protectedHeader?`, `token?`) => [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\nReturns a function that resolves a JWS JOSE Header to a public key object downloaded from a\nremote endpoint returning a JSON Web Key Set, that is, for example, an OAuth 2.0 or OIDC\njwks_uri. The JSON Web Key Set is fetched when no key matches the selection process but only as\nfrequently as the `cooldownDuration` option allows to prevent abuse.\n\nIt uses the \"alg\" (JWS Algorithm) Header Parameter to determine the right JWK \"kty\" (Key Type),\nthen proceeds to match the JWK \"kid\" (Key ID) with one found in the JWS Header Parameters (if\nthere is one) while also respecting the JWK \"use\" (Public Key Use) and JWK \"key_ops\" (Key\nOperations) Parameters (if they are present on the JWK).\n\nOnly a single public key must match the selection process. As shown in the example below when\nmultiple keys get matched it is possible to opt-in to iterate over the matched keys and attempt\nverification in an iterative manner.\n\n> [!NOTE]\\\n> The function's purpose is to resolve public keys used for verifying signatures and will not work\n> for public encryption keys.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/jwks/remote'`.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `url` | [`URL`](https://developer.mozilla.org/docs/Web/API/URL) | URL to fetch the JSON Web Key Set from. |\n| `options?` | [`RemoteJWKSetOptions`](../interfaces/RemoteJWKSetOptions.md) | Options for the remote JSON Web Key Set. |\n\n## Returns\n\n(`protectedHeader?`, `token?`) => [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\n## Examples\n\n```js\nconst JWKS = jose.createRemoteJWKSet(new URL('https://www.googleapis.com/oauth2/v3/certs'))\n\nconst { payload, protectedHeader } = await jose.jwtVerify(jwt, JWKS, {\n  issuer: 'urn:example:issuer',\n  audience: 'urn:example:audience',\n})\nconsole.log(protectedHeader)\nconsole.log(payload)\n```\n\nOpting-in to multiple JWKS matches using `createRemoteJWKSet`\n\n```js\nconst options = {\n  issuer: 'urn:example:issuer',\n  audience: 'urn:example:audience',\n}\nconst { payload, protectedHeader } = await jose\n  .jwtVerify(jwt, JWKS, options)\n  .catch(async (error) => {\n    if (error?.code === 'ERR_JWKS_MULTIPLE_MATCHING_KEYS') {\n      for await (const publicKey of error) {\n        try {\n          return await jose.jwtVerify(jwt, publicKey, options)\n        } catch (innerError) {\n          if (innerError?.code === 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') {\n            continue\n          }\n          throw innerError\n        }\n      }\n      throw new jose.errors.JWSSignatureVerificationFailed()\n    }\n\n    throw error\n  })\nconsole.log(protectedHeader)\nconsole.log(payload)\n```\n"
  },
  {
    "path": "docs/jwks/remote/interfaces/ExportedJWKSCache.md",
    "content": "# Interface: ExportedJWKSCache\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nSee [jwksCache](../variables/jwksCache.md).\n\n## Properties\n\n### jwks\n\n• **jwks**: [`JSONWebKeySet`](../../../types/interfaces/JSONWebKeySet.md)\n\nCurrent cached JSON Web Key Set\n\n***\n\n### uat\n\n• **uat**: `number`\n\nLast updated at timestamp (seconds since epoch)\n"
  },
  {
    "path": "docs/jwks/remote/interfaces/RemoteJWKSetOptions.md",
    "content": "# Interface: RemoteJWKSetOptions\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nOptions for the remote JSON Web Key Set.\n\n## Properties\n\n### \\[customFetch\\]?\n\n• `optional` **\\[customFetch\\]?**: [`FetchImplementation`](../type-aliases/FetchImplementation.md)\n\nSee [customFetch](../variables/customFetch.md).\n\n***\n\n### \\[jwksCache\\]?\n\n• `optional` **\\[jwksCache\\]?**: [`JWKSCacheInput`](../type-aliases/JWKSCacheInput.md)\n\nSee [jwksCache](../variables/jwksCache.md).\n\n***\n\n### cacheMaxAge?\n\n• `optional` **cacheMaxAge?**: `number`\n\nMaximum time (in milliseconds) between successful HTTP requests. Default is 600000 (10\nminutes).\n\n***\n\n### cooldownDuration?\n\n• `optional` **cooldownDuration?**: `number`\n\nDuration (in milliseconds) for which no more HTTP requests will be triggered after a previous\nsuccessful fetch. Default is 30000 (30 seconds).\n\n***\n\n### headers?\n\n• `optional` **headers?**: [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)\\<`string`, `string`\\>\n\nHeaders to be sent with the HTTP request.\n\n***\n\n### timeoutDuration?\n\n• `optional` **timeoutDuration?**: `number`\n\nTimeout (in milliseconds) for the HTTP request. When reached the request will be aborted and\nthe verification will fail. Default is 5000 (5 seconds).\n"
  },
  {
    "path": "docs/jwks/remote/type-aliases/FetchImplementation.md",
    "content": "# Type Alias: FetchImplementation\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n• **FetchImplementation** = (`url`, `options`) => [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Response`](https://developer.mozilla.org/docs/Web/API/Response)\\>\n\nSee [customFetch](../variables/customFetch.md).\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `url` | `string` | - |\n| `options` | \\{ `headers`: [`Headers`](https://developer.mozilla.org/docs/Web/API/Headers); `method`: `\"GET\"`; `redirect`: `\"manual\"`; `signal`: [`AbortSignal`](https://developer.mozilla.org/docs/Web/API/AbortSignal); \\} | - |\n| `options.headers` | [`Headers`](https://developer.mozilla.org/docs/Web/API/Headers) | HTTP Headers |\n| `options.method` | `\"GET\"` | The [request method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) |\n| `options.redirect` | `\"manual\"` | See [Request.redirect](https://developer.mozilla.org/docs/Web/API/Request/redirect) |\n| `options.signal` | [`AbortSignal`](https://developer.mozilla.org/docs/Web/API/AbortSignal) | - |\n\n## Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Response`](https://developer.mozilla.org/docs/Web/API/Response)\\>\n"
  },
  {
    "path": "docs/jwks/remote/type-aliases/JWKSCacheInput.md",
    "content": "# Type Alias: JWKSCacheInput\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n• **JWKSCacheInput** = [`ExportedJWKSCache`](../interfaces/ExportedJWKSCache.md) \\| [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)\\<`string`, `never`\\>\n\nSee [jwksCache](../variables/jwksCache.md).\n"
  },
  {
    "path": "docs/jwks/remote/variables/customFetch.md",
    "content": "# Variable: customFetch\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n• `const` **customFetch**: unique `symbol`\n\nWhen passed to [createRemoteJWKSet](../functions/createRemoteJWKSet.md) this allows the resolver\nto make use of advanced fetch configurations, HTTP Proxies, retry on network errors, etc.\n\n> [!NOTE]\\\n> Known caveat: Expect Type-related issues when passing the inputs through to fetch-like modules,\n> they hardly ever get their typings inline with actual fetch, you should `@ts-expect-error` them.\n\n## Examples\n\nUsing [sindresorhus/ky](https://github.com/sindresorhus/ky) for retries and its hooks feature for\nlogging outgoing requests and their responses.\n\n```ts\nimport ky from 'ky'\n\nlet logRequest!: (request: Request) => void\nlet logResponse!: (request: Request, response: Response) => void\nlet logRetry!: (request: Request, error: Error, retryCount: number) => void\n\nconst JWKS = jose.createRemoteJWKSet(url, {\n  [jose.customFetch]: (...args) =>\n    ky(args[0], {\n      ...args[1],\n      hooks: {\n        beforeRequest: [\n          (request) => {\n            logRequest(request)\n          },\n        ],\n        beforeRetry: [\n          ({ request, error, retryCount }) => {\n            logRetry(request, error, retryCount)\n          },\n        ],\n        afterResponse: [\n          (request, _, response) => {\n            logResponse(request, response)\n          },\n        ],\n      },\n    }),\n})\n```\n\nUsing [nodejs/undici](https://github.com/nodejs/undici) to detect and use HTTP proxies.\n\n```ts\nimport * as undici from 'undici'\n\n// see https://undici.nodejs.org/#/docs/api/EnvHttpProxyAgent\nlet envHttpProxyAgent = new undici.EnvHttpProxyAgent()\n\n// @ts-ignore\nconst JWKS = jose.createRemoteJWKSet(url, {\n  [jose.customFetch]: (...args) => {\n    // @ts-ignore\n    return undici.fetch(args[0], { ...args[1], dispatcher: envHttpProxyAgent }) // prettier-ignore\n  },\n})\n```\n\nUsing [nodejs/undici](https://github.com/nodejs/undici) to automatically retry network errors.\n\n```ts\nimport * as undici from 'undici'\n\n// see https://undici.nodejs.org/#/docs/api/RetryAgent\nlet retryAgent = new undici.RetryAgent(new undici.Agent(), {\n  statusCodes: [],\n  errorCodes: [\n    'ECONNRESET',\n    'ECONNREFUSED',\n    'ENOTFOUND',\n    'ENETDOWN',\n    'ENETUNREACH',\n    'EHOSTDOWN',\n    'UND_ERR_SOCKET',\n  ],\n})\n\n// @ts-ignore\nconst JWKS = jose.createRemoteJWKSet(url, {\n  [jose.customFetch]: (...args) => {\n    // @ts-ignore\n    return undici.fetch(args[0], { ...args[1], dispatcher: retryAgent }) // prettier-ignore\n  },\n})\n```\n\nUsing [nodejs/undici](https://github.com/nodejs/undici) to mock responses in tests.\n\n```ts\nimport * as undici from 'undici'\n\n// see https://undici.nodejs.org/#/docs/api/MockAgent\nlet mockAgent = new undici.MockAgent()\nmockAgent.disableNetConnect()\n\n// @ts-ignore\nconst JWKS = jose.createRemoteJWKSet(url, {\n  [jose.customFetch]: (...args) => {\n    // @ts-ignore\n    return undici.fetch(args[0], { ...args[1], dispatcher: mockAgent }) // prettier-ignore\n  },\n})\n```\n"
  },
  {
    "path": "docs/jwks/remote/variables/jwksCache.md",
    "content": "# Variable: jwksCache\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n• `const` **jwksCache**: unique `symbol`\n\n> [!WARNING]\\\n> This option has security implications that must be understood, assessed for applicability, and\n> accepted before use. It is critical that the JSON Web Key Set cache only be writable by your own\n> code.\n\nThis option is intended for cloud computing runtimes that cannot keep an in memory cache between\ntheir code's invocations. Use in runtimes where an in memory cache between requests is available\nis not desirable.\n\nWhen passed to [createRemoteJWKSet](../functions/createRemoteJWKSet.md) this allows the passed in\nobject to:\n\n- Serve as an initial value for the JSON Web Key Set that the module would otherwise need to\n  trigger an HTTP request for\n- Have the JSON Web Key Set the function optionally ended up triggering an HTTP request for\n  assigned to it as properties\n\nThe intended use pattern is:\n\n- Before verifying with [createRemoteJWKSet](../functions/createRemoteJWKSet.md) you pull the\n  previously cached object from a low-latency key-value store offered by the cloud computing\n  runtime it is executed on;\n- Default to an empty object `{}` instead when there's no previously cached value;\n- Pass it in as [\\[jwksCache\\]](../interfaces/RemoteJWKSetOptions.md);\n- Afterwards, update the key-value storage if the [`uat`](../interfaces/ExportedJWKSCache.md#uat) property of\n  the object has changed.\n\n## Example\n\n```ts\n// Prerequisites\nlet url!: URL\nlet jwt!: string\nlet getPreviouslyCachedJWKS!: () => Promise<jose.ExportedJWKSCache>\nlet storeNewJWKScache!: (cache: jose.ExportedJWKSCache) => Promise<void>\n\n// Load JSON Web Key Set cache\nconst jwksCache: jose.JWKSCacheInput = (await getPreviouslyCachedJWKS()) || {}\nconst { uat } = jwksCache\n\nconst JWKS = jose.createRemoteJWKSet(url, {\n  [jose.jwksCache]: jwksCache,\n})\n\n// Use JSON Web Key Set cache\nawait jose.jwtVerify(jwt, JWKS)\n\nif (uat !== jwksCache.uat) {\n  // Update JSON Web Key Set cache\n  await storeNewJWKScache(jwksCache)\n}\n```\n"
  },
  {
    "path": "docs/jws/compact/sign/README.md",
    "content": "# jws/compact/sign\n\nSigning JSON Web Signature (JWS) in Compact Serialization\n\n## Classes\n\n- [CompactSign](classes/CompactSign.md)\n"
  },
  {
    "path": "docs/jws/compact/sign/classes/CompactSign.md",
    "content": "# Class: CompactSign\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nThe CompactSign class is used to build and sign Compact JWS strings.\n\nThis class is exported (as a named export) from the main `'jose'` module entry point as well as\nfrom its subpath export `'jose/jws/compact/sign'`.\n\n## Example\n\n```js\nconst jws = await new jose.CompactSign(\n  new TextEncoder().encode('It’s a dangerous business, Frodo, going out your door.'),\n)\n  .setProtectedHeader({ alg: 'ES256' })\n  .sign(privateKey)\n\nconsole.log(jws)\n```\n\n## Constructors\n\n### Constructor\n\n▸ **new CompactSign**(`payload`): `CompactSign`\n\nCompactSign constructor\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `payload` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | Binary representation of the payload to sign. |\n\n#### Returns\n\n`CompactSign`\n\n## Methods\n\n### setProtectedHeader()\n\n▸ **setProtectedHeader**(`protectedHeader`): `this`\n\nSets the JWS Protected Header on the CompactSign object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`CompactJWSHeaderParameters`](../../../../types/interfaces/CompactJWSHeaderParameters.md) | JWS Protected Header. |\n\n#### Returns\n\n`this`\n\n***\n\n### sign()\n\n▸ **sign**(`key`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n\nSigns and resolves the value of the Compact JWS string.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) | Private Key or Secret to sign the JWS with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg). |\n| `options?` | [`SignOptions`](../../../../types/interfaces/SignOptions.md) | JWS Sign options. |\n\n#### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n"
  },
  {
    "path": "docs/jws/compact/verify/README.md",
    "content": "# jws/compact/verify\n\nVerifying JSON Web Signature (JWS) in Compact Serialization\n\n## Interfaces\n\n- [CompactVerifyGetKey](interfaces/CompactVerifyGetKey.md)\n\n## Functions\n\n- [compactVerify](functions/compactVerify.md)\n"
  },
  {
    "path": "docs/jws/compact/verify/functions/compactVerify.md",
    "content": "# Function: compactVerify()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n## Call Signature\n\n▸ **compactVerify**(`jws`, `key`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CompactVerifyResult`](../../../../types/interfaces/CompactVerifyResult.md)\\>\n\nVerifies the signature and format of and afterwards decodes the Compact JWS.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/jws/compact/verify'`.\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jws` | `string` \\| [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | Compact JWS. |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) | Key to verify the JWS with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg). |\n| `options?` | [`VerifyOptions`](../../../../types/interfaces/VerifyOptions.md) | JWS Verify options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CompactVerifyResult`](../../../../types/interfaces/CompactVerifyResult.md)\\>\n\n### Example\n\n```js\nconst jws =\n  'eyJhbGciOiJFUzI1NiJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4.kkAs_gPPxWMI3rHuVlxHaTPfDWDoqdI8jSvuSmqV-8IHIWXg9mcAeC9ggV-45ZHRbiRJ3obUIFo1rHphPA5URg'\n\nconst { payload, protectedHeader } = await jose.compactVerify(jws, publicKey)\n\nconsole.log(protectedHeader)\nconsole.log(new TextDecoder().decode(payload))\n```\n\n## Call Signature\n\n▸ **compactVerify**(`jws`, `getKey`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CompactVerifyResult`](../../../../types/interfaces/CompactVerifyResult.md) & [`ResolvedKey`](../../../../types/interfaces/ResolvedKey.md)\\>\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jws` | `string` \\| [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | Compact JWS. |\n| `getKey` | [`CompactVerifyGetKey`](../interfaces/CompactVerifyGetKey.md) | Function resolving a key to verify the JWS with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg). |\n| `options?` | [`VerifyOptions`](../../../../types/interfaces/VerifyOptions.md) | JWS Verify options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CompactVerifyResult`](../../../../types/interfaces/CompactVerifyResult.md) & [`ResolvedKey`](../../../../types/interfaces/ResolvedKey.md)\\>\n"
  },
  {
    "path": "docs/jws/compact/verify/interfaces/CompactVerifyGetKey.md",
    "content": "# Interface: CompactVerifyGetKey()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nInterface for Compact JWS Verification dynamic key resolution. No token components have been\nverified at the time of this function call.\n\n## See\n\n[createRemoteJWKSet](../../../../jwks/remote/functions/createRemoteJWKSet.md) to verify using a remote JSON Web Key Set.\n\n▸ **CompactVerifyGetKey**(`protectedHeader`, `token`): [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md)\\>\n\nDynamic key resolution function. No token components have been verified at the time of this\nfunction call.\n\nIf a suitable key for the token cannot be matched, throw an error instead.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`CompactJWSHeaderParameters`](../../../../types/interfaces/CompactJWSHeaderParameters.md) | JWE or JWS Protected Header. |\n| `token` | [`FlattenedJWSInput`](../../../../types/interfaces/FlattenedJWSInput.md) | The consumed JWE or JWS token. |\n\n## Returns\n\n[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md)\\>\n"
  },
  {
    "path": "docs/jws/flattened/sign/README.md",
    "content": "# jws/flattened/sign\n\nSigning JSON Web Signature (JWS) in Flattened JSON Serialization\n\n## Classes\n\n- [FlattenedSign](classes/FlattenedSign.md)\n"
  },
  {
    "path": "docs/jws/flattened/sign/classes/FlattenedSign.md",
    "content": "# Class: FlattenedSign\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nThe FlattenedSign class is used to build and sign Flattened JWS objects.\n\nThis class is exported (as a named export) from the main `'jose'` module entry point as well as\nfrom its subpath export `'jose/jws/flattened/sign'`.\n\n## Example\n\n```js\nconst jws = await new jose.FlattenedSign(\n  new TextEncoder().encode('It’s a dangerous business, Frodo, going out your door.'),\n)\n  .setProtectedHeader({ alg: 'ES256' })\n  .sign(privateKey)\n\nconsole.log(jws)\n```\n\n## Constructors\n\n### Constructor\n\n▸ **new FlattenedSign**(`payload`): `FlattenedSign`\n\nFlattenedSign constructor\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `payload` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | Binary representation of the payload to sign. |\n\n#### Returns\n\n`FlattenedSign`\n\n## Methods\n\n### setProtectedHeader()\n\n▸ **setProtectedHeader**(`protectedHeader`): `this`\n\nSets the JWS Protected Header on the FlattenedSign object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`JWSHeaderParameters`](../../../../types/interfaces/JWSHeaderParameters.md) | JWS Protected Header. |\n\n#### Returns\n\n`this`\n\n***\n\n### setUnprotectedHeader()\n\n▸ **setUnprotectedHeader**(`unprotectedHeader`): `this`\n\nSets the JWS Unprotected Header on the FlattenedSign object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `unprotectedHeader` | [`JWSHeaderParameters`](../../../../types/interfaces/JWSHeaderParameters.md) | JWS Unprotected Header. |\n\n#### Returns\n\n`this`\n\n***\n\n### sign()\n\n▸ **sign**(`key`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`FlattenedJWS`](../../../../types/interfaces/FlattenedJWS.md)\\>\n\nSigns and resolves the value of the Flattened JWS object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) | Private Key or Secret to sign the JWS with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg). |\n| `options?` | [`SignOptions`](../../../../types/interfaces/SignOptions.md) | JWS Sign options. |\n\n#### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`FlattenedJWS`](../../../../types/interfaces/FlattenedJWS.md)\\>\n"
  },
  {
    "path": "docs/jws/flattened/verify/README.md",
    "content": "# jws/flattened/verify\n\nVerifying JSON Web Signature (JWS) in Flattened JSON Serialization\n\n## Interfaces\n\n- [FlattenedVerifyGetKey](interfaces/FlattenedVerifyGetKey.md)\n\n## Functions\n\n- [flattenedVerify](functions/flattenedVerify.md)\n"
  },
  {
    "path": "docs/jws/flattened/verify/functions/flattenedVerify.md",
    "content": "# Function: flattenedVerify()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n## Call Signature\n\n▸ **flattenedVerify**(`jws`, `key`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`FlattenedVerifyResult`](../../../../types/interfaces/FlattenedVerifyResult.md)\\>\n\nVerifies the signature and format of and afterwards decodes the Flattened JWS.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/jws/flattened/verify'`.\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jws` | [`FlattenedJWSInput`](../../../../types/interfaces/FlattenedJWSInput.md) | Flattened JWS. |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) | Key to verify the JWS with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg). |\n| `options?` | [`VerifyOptions`](../../../../types/interfaces/VerifyOptions.md) | JWS Verify options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`FlattenedVerifyResult`](../../../../types/interfaces/FlattenedVerifyResult.md)\\>\n\n### Example\n\n```js\nconst decoder = new TextDecoder()\nconst jws = {\n  signature:\n    'FVVOXwj6kD3DqdfD9yYqfT2W9jv-Nop4kOehp_DeDGNB5dQNSPRvntBY6xH3uxlCxE8na9d_kyhYOcanpDJ0EA',\n  payload: 'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',\n  protected: 'eyJhbGciOiJFUzI1NiJ9',\n}\n\nconst { payload, protectedHeader } = await jose.flattenedVerify(jws, publicKey)\n\nconsole.log(protectedHeader)\nconsole.log(decoder.decode(payload))\n```\n\n## Call Signature\n\n▸ **flattenedVerify**(`jws`, `getKey`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`FlattenedVerifyResult`](../../../../types/interfaces/FlattenedVerifyResult.md) & [`ResolvedKey`](../../../../types/interfaces/ResolvedKey.md)\\>\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jws` | [`FlattenedJWSInput`](../../../../types/interfaces/FlattenedJWSInput.md) | Flattened JWS. |\n| `getKey` | [`FlattenedVerifyGetKey`](../interfaces/FlattenedVerifyGetKey.md) | Function resolving a key to verify the JWS with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg). |\n| `options?` | [`VerifyOptions`](../../../../types/interfaces/VerifyOptions.md) | JWS Verify options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`FlattenedVerifyResult`](../../../../types/interfaces/FlattenedVerifyResult.md) & [`ResolvedKey`](../../../../types/interfaces/ResolvedKey.md)\\>\n"
  },
  {
    "path": "docs/jws/flattened/verify/interfaces/FlattenedVerifyGetKey.md",
    "content": "# Interface: FlattenedVerifyGetKey()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nInterface for Flattened JWS Verification dynamic key resolution. No token components have been\nverified at the time of this function call.\n\n## See\n\n[createRemoteJWKSet](../../../../jwks/remote/functions/createRemoteJWKSet.md) to verify using a remote JSON Web Key Set.\n\n▸ **FlattenedVerifyGetKey**(`protectedHeader`, `token`): [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md)\\>\n\nDynamic key resolution function. No token components have been verified at the time of this\nfunction call.\n\nIf a suitable key for the token cannot be matched, throw an error instead.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`JWSHeaderParameters`](../../../../types/interfaces/JWSHeaderParameters.md) \\| `undefined` | JWE or JWS Protected Header. |\n| `token` | [`FlattenedJWSInput`](../../../../types/interfaces/FlattenedJWSInput.md) | The consumed JWE or JWS token. |\n\n## Returns\n\n[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md)\\>\n"
  },
  {
    "path": "docs/jws/general/sign/README.md",
    "content": "# jws/general/sign\n\nSigning JSON Web Signature (JWS) in General JSON Serialization\n\n## Classes\n\n- [GeneralSign](classes/GeneralSign.md)\n\n## Interfaces\n\n- [Signature](interfaces/Signature.md)\n"
  },
  {
    "path": "docs/jws/general/sign/classes/GeneralSign.md",
    "content": "# Class: GeneralSign\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nThe GeneralSign class is used to build and sign General JWS objects.\n\nThis class is exported (as a named export) from the main `'jose'` module entry point as well as\nfrom its subpath export `'jose/jws/general/sign'`.\n\n## Example\n\n```js\nconst jws = await new jose.GeneralSign(\n  new TextEncoder().encode('It’s a dangerous business, Frodo, going out your door.'),\n)\n  .addSignature(ecPrivateKey)\n  .setProtectedHeader({ alg: 'ES256' })\n  .addSignature(rsaPrivateKey)\n  .setProtectedHeader({ alg: 'PS256' })\n  .sign()\n\nconsole.log(jws)\n```\n\n## Constructors\n\n### Constructor\n\n▸ **new GeneralSign**(`payload`): `GeneralSign`\n\nGeneralSign constructor\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `payload` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | Binary representation of the payload to sign. |\n\n#### Returns\n\n`GeneralSign`\n\n## Methods\n\n### addSignature()\n\n▸ **addSignature**(`key`, `options?`): [`Signature`](../interfaces/Signature.md)\n\nAdds an additional signature for the General JWS object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) | Private Key or Secret to sign the individual JWS signature with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg). |\n| `options?` | [`SignOptions`](../../../../types/interfaces/SignOptions.md) | JWS Sign options. |\n\n#### Returns\n\n[`Signature`](../interfaces/Signature.md)\n\n***\n\n### sign()\n\n▸ **sign**(): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralJWS`](../../../../types/interfaces/GeneralJWS.md)\\>\n\nSigns and resolves the value of the General JWS object.\n\n#### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralJWS`](../../../../types/interfaces/GeneralJWS.md)\\>\n"
  },
  {
    "path": "docs/jws/general/sign/interfaces/Signature.md",
    "content": "# Interface: Signature\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nUsed to build General JWS object's individual signatures.\n\n## Methods\n\n### addSignature()\n\n▸ **addSignature**(...`args`): `Signature`\n\nA shorthand for calling addSignature() on the enclosing [GeneralSign](../classes/GeneralSign.md) instance\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| ...`args` | \\[[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md), [`SignOptions`](../../../../types/interfaces/SignOptions.md)\\] |\n\n#### Returns\n\n`Signature`\n\n***\n\n### done()\n\n▸ **done**(): [`GeneralSign`](../classes/GeneralSign.md)\n\nReturns the enclosing [GeneralSign](../classes/GeneralSign.md) instance\n\n#### Returns\n\n[`GeneralSign`](../classes/GeneralSign.md)\n\n***\n\n### setProtectedHeader()\n\n▸ **setProtectedHeader**(`protectedHeader`): `Signature`\n\nSets the JWS Protected Header on the Signature object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`JWSHeaderParameters`](../../../../types/interfaces/JWSHeaderParameters.md) | JWS Protected Header. |\n\n#### Returns\n\n`Signature`\n\n***\n\n### setUnprotectedHeader()\n\n▸ **setUnprotectedHeader**(`unprotectedHeader`): `Signature`\n\nSets the JWS Unprotected Header on the Signature object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `unprotectedHeader` | [`JWSHeaderParameters`](../../../../types/interfaces/JWSHeaderParameters.md) | JWS Unprotected Header. |\n\n#### Returns\n\n`Signature`\n\n***\n\n### sign()\n\n▸ **sign**(...`args`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralJWS`](../../../../types/interfaces/GeneralJWS.md)\\>\n\nA shorthand for calling encrypt() on the enclosing [GeneralSign](../classes/GeneralSign.md) instance\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| ...`args` | \\[\\] |\n\n#### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralJWS`](../../../../types/interfaces/GeneralJWS.md)\\>\n"
  },
  {
    "path": "docs/jws/general/verify/README.md",
    "content": "# jws/general/verify\n\nVerifying JSON Web Signature (JWS) in General JSON Serialization\n\n## Interfaces\n\n- [GeneralVerifyGetKey](interfaces/GeneralVerifyGetKey.md)\n\n## Functions\n\n- [generalVerify](functions/generalVerify.md)\n"
  },
  {
    "path": "docs/jws/general/verify/functions/generalVerify.md",
    "content": "# Function: generalVerify()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n## Call Signature\n\n▸ **generalVerify**(`jws`, `key`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralVerifyResult`](../../../../types/interfaces/GeneralVerifyResult.md)\\>\n\nVerifies the signature and format of and afterwards decodes the General JWS.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/jws/general/verify'`.\n\n> [!NOTE]\\\n> The function iterates over the `signatures` array in the General JWS and returns the verification\n> result of the first signature entry that can be successfully verified. The result only contains\n> the payload, protected header, and unprotected header of that successfully verified signature\n> entry. Other signature entries in the General JWS are not validated, and their headers are not\n> included in the returned result. Recipients of a General JWS should only rely on the returned\n> (verified) data.\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jws` | [`GeneralJWSInput`](../../../../types/interfaces/GeneralJWSInput.md) | General JWS. |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) | Key to verify the JWS with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg). |\n| `options?` | [`VerifyOptions`](../../../../types/interfaces/VerifyOptions.md) | JWS Verify options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralVerifyResult`](../../../../types/interfaces/GeneralVerifyResult.md)\\>\n\n### Example\n\n```js\nconst jws = {\n  payload: 'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',\n  signatures: [\n    {\n      signature:\n        'FVVOXwj6kD3DqdfD9yYqfT2W9jv-Nop4kOehp_DeDGNB5dQNSPRvntBY6xH3uxlCxE8na9d_kyhYOcanpDJ0EA',\n      protected: 'eyJhbGciOiJFUzI1NiJ9',\n    },\n  ],\n}\n\nconst { payload, protectedHeader } = await jose.generalVerify(jws, publicKey)\n\nconsole.log(protectedHeader)\nconsole.log(new TextDecoder().decode(payload))\n```\n\n## Call Signature\n\n▸ **generalVerify**(`jws`, `getKey`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralVerifyResult`](../../../../types/interfaces/GeneralVerifyResult.md) & [`ResolvedKey`](../../../../types/interfaces/ResolvedKey.md)\\>\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jws` | [`GeneralJWSInput`](../../../../types/interfaces/GeneralJWSInput.md) | General JWS. |\n| `getKey` | [`GeneralVerifyGetKey`](../interfaces/GeneralVerifyGetKey.md) | Function resolving a key to verify the JWS with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg). |\n| `options?` | [`VerifyOptions`](../../../../types/interfaces/VerifyOptions.md) | JWS Verify options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GeneralVerifyResult`](../../../../types/interfaces/GeneralVerifyResult.md) & [`ResolvedKey`](../../../../types/interfaces/ResolvedKey.md)\\>\n"
  },
  {
    "path": "docs/jws/general/verify/interfaces/GeneralVerifyGetKey.md",
    "content": "# Interface: GeneralVerifyGetKey()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nInterface for General JWS Verification dynamic key resolution. No token components have been\nverified at the time of this function call.\n\n## See\n\n[createRemoteJWKSet](../../../../jwks/remote/functions/createRemoteJWKSet.md) to verify using a remote JSON Web Key Set.\n\n▸ **GeneralVerifyGetKey**(`protectedHeader`, `token`): [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md)\\>\n\nDynamic key resolution function. No token components have been verified at the time of this\nfunction call.\n\nIf a suitable key for the token cannot be matched, throw an error instead.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`JWSHeaderParameters`](../../../../types/interfaces/JWSHeaderParameters.md) | JWE or JWS Protected Header. |\n| `token` | [`FlattenedJWSInput`](../../../../types/interfaces/FlattenedJWSInput.md) | The consumed JWE or JWS token. |\n\n## Returns\n\n[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../../types/interfaces/KeyObject.md)\\>\n"
  },
  {
    "path": "docs/jwt/decrypt/README.md",
    "content": "# jwt/decrypt\n\nJSON Web Token (JWT) Decryption (JWT is in JWE format)\n\n## Interfaces\n\n- [JWTDecryptGetKey](interfaces/JWTDecryptGetKey.md)\n- [JWTDecryptOptions](interfaces/JWTDecryptOptions.md)\n\n## Functions\n\n- [jwtDecrypt](functions/jwtDecrypt.md)\n"
  },
  {
    "path": "docs/jwt/decrypt/functions/jwtDecrypt.md",
    "content": "# Function: jwtDecrypt()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n## Call Signature\n\n▸ **jwtDecrypt**\\<`PayloadType`\\>(`jwt`, `key`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`JWTDecryptResult`](../../../types/interfaces/JWTDecryptResult.md)\\<`PayloadType`\\>\\>\n\nVerifies the JWT format (to be a JWE Compact format), decrypts the ciphertext, validates the JWT\nClaims Set.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/jwt/decrypt'`.\n\n### Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `PayloadType` | [`JWTPayload`](../../../types/interfaces/JWTPayload.md) |\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwt` | `string` \\| [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | JSON Web Token value (encoded as JWE). |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md) | Private Key or Secret to decrypt and verify the JWT with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg). |\n| `options?` | [`JWTDecryptOptions`](../interfaces/JWTDecryptOptions.md) | JWT Decryption and JWT Claims Set validation options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`JWTDecryptResult`](../../../types/interfaces/JWTDecryptResult.md)\\<`PayloadType`\\>\\>\n\n### Example\n\n```js\nconst secret = jose.base64url.decode('zH4NRP1HMALxxCFnRZABFA7GOJtzU_gIj02alfL1lvI')\nconst jwt =\n  'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..MB66qstZBPxAXKdsjet_lA.WHbtJTl4taHp7otOHLq3hBvv0yNPsPEKHYInmCPdDDeyV1kU-f-tGEiU4FxlSqkqAT2hVs8_wMNiQFAzPU1PUgIqWCPsBrPP3TtxYsrtwagpn4SvCsUsx0Mhw9ZhliAO8CLmCBQkqr_T9AcYsz5uZw.7nX9m7BGUu_u1p1qFHzyIg'\n\nconst { payload, protectedHeader } = await jose.jwtDecrypt(jwt, secret, {\n  issuer: 'urn:example:issuer',\n  audience: 'urn:example:audience',\n})\n\nconsole.log(protectedHeader)\nconsole.log(payload)\n```\n\n## Call Signature\n\n▸ **jwtDecrypt**\\<`PayloadType`\\>(`jwt`, `getKey`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`JWTDecryptResult`](../../../types/interfaces/JWTDecryptResult.md)\\<`PayloadType`\\> & [`ResolvedKey`](../../../types/interfaces/ResolvedKey.md)\\>\n\n### Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `PayloadType` | [`JWTPayload`](../../../types/interfaces/JWTPayload.md) |\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwt` | `string` \\| [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | JSON Web Token value (encoded as JWE). |\n| `getKey` | [`JWTDecryptGetKey`](../interfaces/JWTDecryptGetKey.md) | Function resolving Private Key or Secret to decrypt and verify the JWT with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg). |\n| `options?` | [`JWTDecryptOptions`](../interfaces/JWTDecryptOptions.md) | JWT Decryption and JWT Claims Set validation options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`JWTDecryptResult`](../../../types/interfaces/JWTDecryptResult.md)\\<`PayloadType`\\> & [`ResolvedKey`](../../../types/interfaces/ResolvedKey.md)\\>\n"
  },
  {
    "path": "docs/jwt/decrypt/interfaces/JWTDecryptGetKey.md",
    "content": "# Interface: JWTDecryptGetKey()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nInterface for JWT Decryption dynamic key resolution. No token components have been verified at\nthe time of this function call.\n\n▸ **JWTDecryptGetKey**(`protectedHeader`, `token`): [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md)\\>\n\nDynamic key resolution function. No token components have been verified at the time of this\nfunction call.\n\nIf a suitable key for the token cannot be matched, throw an error instead.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`CompactJWEHeaderParameters`](../../../types/interfaces/CompactJWEHeaderParameters.md) | JWE or JWS Protected Header. |\n| `token` | [`FlattenedJWE`](../../../types/interfaces/FlattenedJWE.md) | The consumed JWE or JWS token. |\n\n## Returns\n\n[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md)\\>\n"
  },
  {
    "path": "docs/jwt/decrypt/interfaces/JWTDecryptOptions.md",
    "content": "# Interface: JWTDecryptOptions\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nCombination of JWE Decryption options and JWT Claims Set verification options.\n\n## Properties\n\n### audience?\n\n• `optional` **audience?**: `string` \\| `string`[]\n\nExpected JWT \"aud\" (Audience) Claim value(s).\n\nThis option makes the JWT \"aud\" (Audience) Claim presence required.\n\n***\n\n### clockTolerance?\n\n• `optional` **clockTolerance?**: `string` \\| `number`\n\nClock skew tolerance\n\n- In seconds when number (e.g. 5)\n- Resolved into a number of seconds when a string (e.g. \"5 seconds\", \"10 minutes\", \"2 hours\").\n\nUsed when validating the JWT \"nbf\" (Not Before) and \"exp\" (Expiration Time) claims, and when\nvalidating the \"iat\" (Issued At) claim if the [`maxTokenAge` option](../../../types/interfaces/JWTClaimVerificationOptions.md#maxtokenage) is set.\n\n***\n\n### contentEncryptionAlgorithms?\n\n• `optional` **contentEncryptionAlgorithms?**: `string`[]\n\nA list of accepted JWE \"enc\" (Encryption Algorithm) Header Parameter values. By default all\n\"enc\" (Encryption Algorithm) values applicable for the used key/secret are allowed.\n\n***\n\n### crit?\n\n• `optional` **crit?**: `object`\n\nAn object with keys representing recognized \"crit\" (Critical) Header Parameter names. The value\nfor those is either `true` or `false`. `true` when the Header Parameter MUST be integrity\nprotected, `false` when it's irrelevant.\n\nThis makes the \"Extension Header Parameter \"...\" is not recognized\" error go away.\n\nUse this when a given JWS/JWT/JWE profile requires the use of proprietary non-registered \"crit\"\n(Critical) Header Parameters. This will only make sure the Header Parameter is syntactically\ncorrect when provided and that it is optionally integrity protected. It will not process the\nHeader Parameter in any way or reject the operation if it is missing. You MUST still verify the\nHeader Parameter was present and process it according to the profile's validation steps after\nthe operation succeeds.\n\nThe JWS extension Header Parameter `b64` is always recognized and processed properly. No other\nregistered Header Parameters that need this kind of default built-in treatment are currently\navailable.\n\n#### Index Signature\n\n\\[`propName`: `string`\\]: `boolean`\n\n***\n\n### currentDate?\n\n• `optional` **currentDate?**: [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date)\n\nDate to use when comparing NumericDate claims, defaults to `new Date()`.\n\n***\n\n### issuer?\n\n• `optional` **issuer?**: `string` \\| `string`[]\n\nExpected JWT \"iss\" (Issuer) Claim value(s).\n\nThis option makes the JWT \"iss\" (Issuer) Claim presence required.\n\n***\n\n### keyManagementAlgorithms?\n\n• `optional` **keyManagementAlgorithms?**: `string`[]\n\nA list of accepted JWE \"alg\" (Algorithm) Header Parameter values. By default all \"alg\"\n(Algorithm) Header Parameter values applicable for the used key/secret are allowed except for\nall PBES2 Key Management Algorithms, these need to be explicitly allowed using this option.\n\n***\n\n### maxDecompressedLength?\n\n• `optional` **maxDecompressedLength?**: `number`\n\nMaximum allowed size (in bytes) of the decompressed plaintext when the JWE `\"zip\"` (Compression\nAlgorithm) Header Parameter is present. By default this value is set to 250000 (250 KB). The\nvalue must be `0`, a positive safe integer, or `Infinity`.\n\nSet to `0` to reject all compressed JWEs during decryption.\n\nSet to `Infinity` to disable the decompressed size limit.\n\n***\n\n### maxPBES2Count?\n\n• `optional` **maxPBES2Count?**: `number`\n\n(PBES2 Key Management Algorithms only) Maximum allowed \"p2c\" (PBES2 Count) Header Parameter\nvalue. The PBKDF2 iteration count defines the algorithm's computational expense. By default\nthis value is set to 10000.\n\n***\n\n### maxTokenAge?\n\n• `optional` **maxTokenAge?**: `string` \\| `number`\n\nMaximum time elapsed (in seconds) from the JWT \"iat\" (Issued At) Claim value.\n\n- In seconds when number (e.g. 5)\n- Resolved into a number of seconds when a string (e.g. \"5 seconds\", \"10 minutes\", \"2 hours\").\n\nThis option makes the JWT \"iat\" (Issued At) Claim presence required.\n\n***\n\n### requiredClaims?\n\n• `optional` **requiredClaims?**: `string`[]\n\nArray of required Claim Names that must be present in the JWT Claims Set. Default is that: if\nthe [`issuer` option](../../../types/interfaces/JWTClaimVerificationOptions.md#issuer) is set, then JWT \"iss\" (Issuer) Claim must be present; if the\n[`audience` option](../../../types/interfaces/JWTClaimVerificationOptions.md#audience) is set, then JWT \"aud\" (Audience) Claim must be present; if\nthe [`subject` option](../../../types/interfaces/JWTClaimVerificationOptions.md#subject) is set, then JWT \"sub\" (Subject) Claim must be present; if\nthe [`maxTokenAge` option](../../../types/interfaces/JWTClaimVerificationOptions.md#maxtokenage) is set, then JWT \"iat\" (Issued At) Claim must be\npresent.\n\n***\n\n### subject?\n\n• `optional` **subject?**: `string`\n\nExpected JWT \"sub\" (Subject) Claim value.\n\nThis option makes the JWT \"sub\" (Subject) Claim presence required.\n\n***\n\n### typ?\n\n• `optional` **typ?**: `string`\n\nExpected JWT \"typ\" (Type) Header Parameter value.\n\nThis option makes the JWT \"typ\" (Type) Header Parameter presence required.\n"
  },
  {
    "path": "docs/jwt/encrypt/README.md",
    "content": "# jwt/encrypt\n\nJSON Web Token (JWT) Encryption (JWT is in JWE format)\n\n## Classes\n\n- [EncryptJWT](classes/EncryptJWT.md)\n"
  },
  {
    "path": "docs/jwt/encrypt/classes/EncryptJWT.md",
    "content": "# Class: EncryptJWT\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nThe EncryptJWT class is used to build and encrypt Compact JWE formatted JSON Web Tokens.\n\nThis class is exported (as a named export) from the main `'jose'` module entry point as well as\nfrom its subpath export `'jose/jwt/encrypt'`.\n\n## Example\n\n```js\nconst secret = jose.base64url.decode('zH4NRP1HMALxxCFnRZABFA7GOJtzU_gIj02alfL1lvI')\nconst jwt = await new jose.EncryptJWT({ 'urn:example:claim': true })\n  .setProtectedHeader({ alg: 'dir', enc: 'A128CBC-HS256' })\n  .setIssuedAt()\n  .setIssuer('urn:example:issuer')\n  .setAudience('urn:example:audience')\n  .setExpirationTime('2h')\n  .encrypt(secret)\n\nconsole.log(jwt)\n```\n\n## Constructors\n\n### Constructor\n\n▸ **new EncryptJWT**(`payload?`): `EncryptJWT`\n\nEncryptJWT constructor\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `payload` | [`JWTPayload`](../../../types/interfaces/JWTPayload.md) | The JWT Claims Set object. Defaults to an empty object. |\n\n#### Returns\n\n`EncryptJWT`\n\n## Methods\n\n### encrypt()\n\n▸ **encrypt**(`key`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n\nEncrypts and returns the JWT.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md) | Public Key or Secret to encrypt the JWT with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg). |\n| `options?` | [`EncryptOptions`](../../../types/interfaces/EncryptOptions.md) | JWE Encryption options. |\n\n#### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n\n***\n\n### replicateAudienceAsHeader()\n\n▸ **replicateAudienceAsHeader**(): `this`\n\nReplicates the \"aud\" (Audience) Claim as a JWE Protected Header Parameter.\n\n#### Returns\n\n`this`\n\n#### See\n\n[RFC7519#section-5.3](https://www.rfc-editor.org/rfc/rfc7519#section-5.3)\n\n***\n\n### replicateIssuerAsHeader()\n\n▸ **replicateIssuerAsHeader**(): `this`\n\nReplicates the \"iss\" (Issuer) Claim as a JWE Protected Header Parameter.\n\n#### Returns\n\n`this`\n\n#### See\n\n[RFC7519#section-5.3](https://www.rfc-editor.org/rfc/rfc7519#section-5.3)\n\n***\n\n### replicateSubjectAsHeader()\n\n▸ **replicateSubjectAsHeader**(): `this`\n\nReplicates the \"sub\" (Subject) Claim as a JWE Protected Header Parameter.\n\n#### Returns\n\n`this`\n\n#### See\n\n[RFC7519#section-5.3](https://www.rfc-editor.org/rfc/rfc7519#section-5.3)\n\n***\n\n### setAudience()\n\n▸ **setAudience**(`audience`): `this`\n\nSet the \"aud\" (Audience) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `audience` | `string` \\| `string`[] | \"aud\" (Audience) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### ~~setContentEncryptionKey()~~\n\n▸ **setContentEncryptionKey**(`cek`): `this`\n\nSets a content encryption key to use, by default a random suitable one is generated for the JWE\nenc\" (Encryption Algorithm) Header Parameter.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `cek` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | JWE Content Encryption Key. |\n\n#### Returns\n\n`this`\n\n#### Deprecated\n\nYou should not use this method. It is only really intended for test and vector\n  validation purposes.\n\n***\n\n### setExpirationTime()\n\n▸ **setExpirationTime**(`input`): `this`\n\nSet the \"exp\" (Expiration Time) Claim.\n\n- If a `number` is passed as an argument it is used as the claim directly.\n- If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n  claim.\n- If a `string` is passed as an argument it is resolved to a time span, and then added to the\n  current unix timestamp and used as the claim.\n\nFormat used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\nday\".\n\nValid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n\"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n\"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\nalias for a year.\n\nIf the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\nsubtracted from the current unix timestamp. A \"from now\" suffix can also be used for\nreadability when adding to the current unix timestamp.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `input` | `string` \\| `number` \\| [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | \"exp\" (Expiration Time) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### ~~setInitializationVector()~~\n\n▸ **setInitializationVector**(`iv`): `this`\n\nSets the JWE Initialization Vector to use for content encryption, by default a random suitable\none is generated for the JWE enc\" (Encryption Algorithm) Header Parameter.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `iv` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | JWE Initialization Vector. |\n\n#### Returns\n\n`this`\n\n#### Deprecated\n\nYou should not use this method. It is only really intended for test and vector\n  validation purposes.\n\n***\n\n### setIssuedAt()\n\n▸ **setIssuedAt**(`input?`): `this`\n\nSet the \"iat\" (Issued At) Claim.\n\n- If no argument is used the current unix timestamp is used as the claim.\n- If a `number` is passed as an argument it is used as the claim directly.\n- If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n  claim.\n- If a `string` is passed as an argument it is resolved to a time span, and then added to the\n  current unix timestamp and used as the claim.\n\nFormat used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\nday\".\n\nValid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n\"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n\"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\nalias for a year.\n\nIf the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\nsubtracted from the current unix timestamp. A \"from now\" suffix can also be used for\nreadability when adding to the current unix timestamp.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `input?` | `string` \\| `number` \\| [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | \"iat\" (Expiration Time) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setIssuer()\n\n▸ **setIssuer**(`issuer`): `this`\n\nSet the \"iss\" (Issuer) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `issuer` | `string` | \"Issuer\" Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setJti()\n\n▸ **setJti**(`jwtId`): `this`\n\nSet the \"jti\" (JWT ID) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwtId` | `string` | \"jti\" (JWT ID) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setKeyManagementParameters()\n\n▸ **setKeyManagementParameters**(`parameters`): `this`\n\nSets the JWE Key Management parameters to be used when encrypting.\n\n(ECDH-ES) Use of this method is needed for ECDH based algorithms to set the \"apu\" (Agreement\nPartyUInfo) or \"apv\" (Agreement PartyVInfo) parameters.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `parameters` | [`JWEKeyManagementHeaderParameters`](../../../types/interfaces/JWEKeyManagementHeaderParameters.md) | JWE Key Management parameters. |\n\n#### Returns\n\n`this`\n\n***\n\n### setNotBefore()\n\n▸ **setNotBefore**(`input`): `this`\n\nSet the \"nbf\" (Not Before) Claim.\n\n- If a `number` is passed as an argument it is used as the claim directly.\n- If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n  claim.\n- If a `string` is passed as an argument it is resolved to a time span, and then added to the\n  current unix timestamp and used as the claim.\n\nFormat used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\nday\".\n\nValid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n\"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n\"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\nalias for a year.\n\nIf the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\nsubtracted from the current unix timestamp. A \"from now\" suffix can also be used for\nreadability when adding to the current unix timestamp.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `input` | `string` \\| `number` \\| [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | \"nbf\" (Not Before) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setProtectedHeader()\n\n▸ **setProtectedHeader**(`protectedHeader`): `this`\n\nSets the JWE Protected Header on the EncryptJWT object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`CompactJWEHeaderParameters`](../../../types/interfaces/CompactJWEHeaderParameters.md) | JWE Protected Header. Must contain an \"alg\" (JWE Algorithm) and \"enc\" (JWE Encryption Algorithm) properties. |\n\n#### Returns\n\n`this`\n\n***\n\n### setSubject()\n\n▸ **setSubject**(`subject`): `this`\n\nSet the \"sub\" (Subject) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `subject` | `string` | \"sub\" (Subject) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n"
  },
  {
    "path": "docs/jwt/sign/README.md",
    "content": "# jwt/sign\n\nJSON Web Token (JWT) Signing (JWT is in JWS format)\n\n## Classes\n\n- [SignJWT](classes/SignJWT.md)\n"
  },
  {
    "path": "docs/jwt/sign/classes/SignJWT.md",
    "content": "# Class: SignJWT\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nThe SignJWT class is used to build and sign Compact JWS formatted JSON Web Tokens.\n\nThis class is exported (as a named export) from the main `'jose'` module entry point as well as\nfrom its subpath export `'jose/jwt/sign'`.\n\n## Examples\n\nUsage with a symmetric secret\n\n```js\nconst secret = new TextEncoder().encode(\n  'cc7e0d44fd473002f1c42167459001140ec6389b7353f8088f4d9a95f2f596f2',\n)\nconst alg = 'HS256'\n\nconst jwt = await new jose.SignJWT({ 'urn:example:claim': true })\n  .setProtectedHeader({ alg })\n  .setIssuedAt()\n  .setIssuer('urn:example:issuer')\n  .setAudience('urn:example:audience')\n  .setExpirationTime('2h')\n  .sign(secret)\n\nconsole.log(jwt)\n```\n\nUsage with a private PKCS#8 encoded RSA key\n\n```js\nconst alg = 'RS256'\nconst pkcs8 = `-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDCFg4UrY5xtulv\n/NXKmL1J4qI1SopAfTNMo3X7p+kJO7plqUYjzaztcre1qfh0m33Sm1Q8oPbO/GpP\nMU1/HgcceytgJ/b4UwufVVMl9BrMDYG8moDBylbVupFQS3Ly1L9i/iFG9Z9A9xzY\nZzf799A45bnvNXL6s2glzvjiRvfQ2NDF0anTcnZLcYtC7ugq1IMM+ihAcPfw8Qw2\nchN/SmP4qAM+PKaQwagmU7doqmmyN9u38AfoYZ1GCFhEs5TBBT6H6h9YdHeVtiIq\n1c+fl03biSIfLrV7dUBD39gBmXBcL/30Ya3D82mCEUC4zg/UkOfQOmkmV3Lc8YUL\nQZ8EJkBLAgMBAAECggEAVuVE/KEP6323WjpbBdAIv7HGahGrgGANvbxZsIhm34ls\nVOPK0XDegZkhAybMZHjRhp+gwVxX5ChC+J3cUpOBH5FNxElgW6HizD2Jcq6t6LoL\nYgPSrfEHm71iHg8JsgrqfUnGYFzMJmv88C6WdCtpgG/qJV1K00/Ly1G1QKoBffEs\n+v4fAMJrCbUdCz1qWto+PU+HLMEo+krfEpGgcmtZeRlDADh8cETMQlgQfQX2VWq/\naAP4a1SXmo+j0cvRU4W5Fj0RVwNesIpetX2ZFz4p/JmB5sWFEj/fC7h5z2lq+6Bm\ne2T3BHtXkIxoBW0/pYVnASC8P2puO5FnVxDmWuHDYQKBgQDTuuBd3+0tSFVEX+DU\n5qpFmHm5nyGItZRJTS+71yg5pBxq1KqNCUjAtbxR0q//fwauakh+BwRVCPOrqsUG\njBSb3NYE70Srp6elqxgkE54PwQx4Mr6exJPnseM9U4K+hULllf5yjM9edreJE1nV\nNVgFjeyafQhrHKwgr7PERJ/ikwKBgQDqqsT1M+EJLmI1HtCspOG6cu7q3gf/wKRh\nE8tu84i3YyBnI8uJkKy92RNVI5fvpBARe3tjSdM25rr2rcrcmF/5g6Q9ImxZPGCt\n86eOgO9ErNtbc4TEgybsP319UE4O41aKeNiBTAZKoYCxv/dMqG0j4avmWzd+foHq\ngSNUvR2maQKBgQCYeqOsV2B6VPY7KIVFLd0AA9/dwvEmgAYLiA/RShDI+hwQ/5jX\nuxDu37KAhqeC65sHLrmIMUt4Zdr+DRyZK3aIDNEAesPMjw/X6lCXYp1ZISD2yyym\nMFGH8X8CIkstI9Faf9vf6PJKSFrC1/HA7wq17VCwrUzLvrljTMW8meM/CwKBgCpo\n2leGHLFQFKeM/iF1WuYbR1pi7gcmhY6VyTowARFDdOOu8GXYI5/bz0afvCGvAMho\nDJCREv7lC/zww6zCTPYG+HOj+PjXlJFba3ixjIxYwPvyEJiDK1Ge18sB7Fl8dHNq\nC5ayaqCqN1voWYUdGzxU2IA1E/5kVo5O8FesJeOhAoGBAImJbZFf+D5kA32Xxhac\n59lLWBCsocvvbd1cvDMNlRywAAyhsCb1SuX4nEAK9mrSBdfmoF2Nm3eilfsOds0f\nK5mX069IKG82CMqh3Mzptd7e7lyb9lsoGO0BAtjho3cWtha/UZ70vfaMzGuZ6JmQ\nak6k+8+UFd93M4z0Qo74OhXB\n-----END PRIVATE KEY-----`\nconst privateKey = await jose.importPKCS8(pkcs8, alg)\n\nconst jwt = await new jose.SignJWT({ 'urn:example:claim': true })\n  .setProtectedHeader({ alg })\n  .setIssuedAt()\n  .setIssuer('urn:example:issuer')\n  .setAudience('urn:example:audience')\n  .setExpirationTime('2h')\n  .sign(privateKey)\n\nconsole.log(jwt)\n```\n\nUsage with a private JWK encoded RSA key\n\n```js\nconst alg = 'RS256'\nconst jwk = {\n  kty: 'RSA',\n  n: 'whYOFK2Ocbbpb_zVypi9SeKiNUqKQH0zTKN1-6fpCTu6ZalGI82s7XK3tan4dJt90ptUPKD2zvxqTzFNfx4HHHsrYCf2-FMLn1VTJfQazA2BvJqAwcpW1bqRUEty8tS_Yv4hRvWfQPcc2Gc3-_fQOOW57zVy-rNoJc744kb30NjQxdGp03J2S3GLQu7oKtSDDPooQHD38PEMNnITf0pj-KgDPjymkMGoJlO3aKppsjfbt_AH6GGdRghYRLOUwQU-h-ofWHR3lbYiKtXPn5dN24kiHy61e3VAQ9_YAZlwXC_99GGtw_NpghFAuM4P1JDn0DppJldy3PGFC0GfBCZASw',\n  e: 'AQAB',\n  d: 'VuVE_KEP6323WjpbBdAIv7HGahGrgGANvbxZsIhm34lsVOPK0XDegZkhAybMZHjRhp-gwVxX5ChC-J3cUpOBH5FNxElgW6HizD2Jcq6t6LoLYgPSrfEHm71iHg8JsgrqfUnGYFzMJmv88C6WdCtpgG_qJV1K00_Ly1G1QKoBffEs-v4fAMJrCbUdCz1qWto-PU-HLMEo-krfEpGgcmtZeRlDADh8cETMQlgQfQX2VWq_aAP4a1SXmo-j0cvRU4W5Fj0RVwNesIpetX2ZFz4p_JmB5sWFEj_fC7h5z2lq-6Bme2T3BHtXkIxoBW0_pYVnASC8P2puO5FnVxDmWuHDYQ',\n  p: '07rgXd_tLUhVRF_g1OaqRZh5uZ8hiLWUSU0vu9coOaQcatSqjQlIwLW8UdKv_38GrmpIfgcEVQjzq6rFBowUm9zWBO9Eq6enpasYJBOeD8EMeDK-nsST57HjPVOCvoVC5ZX-cozPXna3iRNZ1TVYBY3smn0IaxysIK-zxESf4pM',\n  q: '6qrE9TPhCS5iNR7QrKThunLu6t4H_8CkYRPLbvOIt2MgZyPLiZCsvdkTVSOX76QQEXt7Y0nTNua69q3K3Jhf-YOkPSJsWTxgrfOnjoDvRKzbW3OExIMm7D99fVBODuNWinjYgUwGSqGAsb_3TKhtI-Gr5ls3fn6B6oEjVL0dpmk',\n  dp: 'mHqjrFdgelT2OyiFRS3dAAPf3cLxJoAGC4gP0UoQyPocEP-Y17sQ7t-ygIanguubBy65iDFLeGXa_g0cmSt2iAzRAHrDzI8P1-pQl2KdWSEg9ssspjBRh_F_AiJLLSPRWn_b3-jySkhawtfxwO8Kte1QsK1My765Y0zFvJnjPws',\n  dq: 'KmjaV4YcsVAUp4z-IXVa5htHWmLuByaFjpXJOjABEUN0467wZdgjn9vPRp-8Ia8AyGgMkJES_uUL_PDDrMJM9gb4c6P4-NeUkVtreLGMjFjA-_IQmIMrUZ7XywHsWXx0c2oLlrJqoKo3W-hZhR0bPFTYgDUT_mRWjk7wV6wl46E',\n  qi: 'iYltkV_4PmQDfZfGFpzn2UtYEKyhy-9t3Vy8Mw2VHLAADKGwJvVK5ficQAr2atIF1-agXY2bd6KV-w52zR8rmZfTr0gobzYIyqHczOm13t7uXJv2WygY7QEC2OGjdxa2Fr9RnvS99ozMa5nomZBqTqT7z5QV33czjPRCjvg6FcE',\n}\nconst privateKey = await jose.importJWK(jwk, alg)\n\nconst jwt = await new jose.SignJWT({ 'urn:example:claim': true })\n  .setProtectedHeader({ alg })\n  .setIssuedAt()\n  .setIssuer('urn:example:issuer')\n  .setAudience('urn:example:audience')\n  .setExpirationTime('2h')\n  .sign(privateKey)\n\nconsole.log(jwt)\n```\n\n## Constructors\n\n### Constructor\n\n▸ **new SignJWT**(`payload?`): `SignJWT`\n\nSignJWT constructor\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `payload` | [`JWTPayload`](../../../types/interfaces/JWTPayload.md) | The JWT Claims Set object. Defaults to an empty object. |\n\n#### Returns\n\n`SignJWT`\n\n## Methods\n\n### setAudience()\n\n▸ **setAudience**(`audience`): `this`\n\nSet the \"aud\" (Audience) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `audience` | `string` \\| `string`[] | \"aud\" (Audience) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setExpirationTime()\n\n▸ **setExpirationTime**(`input`): `this`\n\nSet the \"exp\" (Expiration Time) Claim.\n\n- If a `number` is passed as an argument it is used as the claim directly.\n- If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n  claim.\n- If a `string` is passed as an argument it is resolved to a time span, and then added to the\n  current unix timestamp and used as the claim.\n\nFormat used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\nday\".\n\nValid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n\"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n\"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\nalias for a year.\n\nIf the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\nsubtracted from the current unix timestamp. A \"from now\" suffix can also be used for\nreadability when adding to the current unix timestamp.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `input` | `string` \\| `number` \\| [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | \"exp\" (Expiration Time) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setIssuedAt()\n\n▸ **setIssuedAt**(`input?`): `this`\n\nSet the \"iat\" (Issued At) Claim.\n\n- If no argument is used the current unix timestamp is used as the claim.\n- If a `number` is passed as an argument it is used as the claim directly.\n- If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n  claim.\n- If a `string` is passed as an argument it is resolved to a time span, and then added to the\n  current unix timestamp and used as the claim.\n\nFormat used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\nday\".\n\nValid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n\"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n\"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\nalias for a year.\n\nIf the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\nsubtracted from the current unix timestamp. A \"from now\" suffix can also be used for\nreadability when adding to the current unix timestamp.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `input?` | `string` \\| `number` \\| [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | \"iat\" (Expiration Time) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setIssuer()\n\n▸ **setIssuer**(`issuer`): `this`\n\nSet the \"iss\" (Issuer) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `issuer` | `string` | \"Issuer\" Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setJti()\n\n▸ **setJti**(`jwtId`): `this`\n\nSet the \"jti\" (JWT ID) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwtId` | `string` | \"jti\" (JWT ID) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setNotBefore()\n\n▸ **setNotBefore**(`input`): `this`\n\nSet the \"nbf\" (Not Before) Claim.\n\n- If a `number` is passed as an argument it is used as the claim directly.\n- If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n  claim.\n- If a `string` is passed as an argument it is resolved to a time span, and then added to the\n  current unix timestamp and used as the claim.\n\nFormat used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\nday\".\n\nValid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n\"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n\"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\nalias for a year.\n\nIf the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\nsubtracted from the current unix timestamp. A \"from now\" suffix can also be used for\nreadability when adding to the current unix timestamp.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `input` | `string` \\| `number` \\| [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | \"nbf\" (Not Before) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setProtectedHeader()\n\n▸ **setProtectedHeader**(`protectedHeader`): `this`\n\nSets the JWS Protected Header on the SignJWT object.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`JWTHeaderParameters`](../../../types/interfaces/JWTHeaderParameters.md) | JWS Protected Header. Must contain an \"alg\" (JWS Algorithm) property. |\n\n#### Returns\n\n`this`\n\n***\n\n### setSubject()\n\n▸ **setSubject**(`subject`): `this`\n\nSet the \"sub\" (Subject) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `subject` | `string` | \"sub\" (Subject) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### sign()\n\n▸ **sign**(`key`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n\nSigns and returns the JWT.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md) | Private Key or Secret to sign the JWT with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg). |\n| `options?` | [`SignOptions`](../../../types/interfaces/SignOptions.md) | JWT Sign options. |\n\n#### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n"
  },
  {
    "path": "docs/jwt/unsecured/README.md",
    "content": "# jwt/unsecured\n\nUnsecured (unsigned & unencrypted) JSON Web Tokens (JWT)\n\n## Classes\n\n- [UnsecuredJWT](classes/UnsecuredJWT.md)\n\n## Interfaces\n\n- [UnsecuredResult](interfaces/UnsecuredResult.md)\n"
  },
  {
    "path": "docs/jwt/unsecured/classes/UnsecuredJWT.md",
    "content": "# Class: UnsecuredJWT\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nThe UnsecuredJWT class is a utility for dealing with `{ \"alg\": \"none\" }` Unsecured JWTs.\n\nThis class is exported (as a named export) from the main `'jose'` module entry point as well as\nfrom its subpath export `'jose/jwt/unsecured'`.\n\n## Examples\n\nEncoding\n\n```js\nconst unsecuredJwt = new jose.UnsecuredJWT({ 'urn:example:claim': true })\n  .setIssuedAt()\n  .setIssuer('urn:example:issuer')\n  .setAudience('urn:example:audience')\n  .setExpirationTime('2h')\n  .encode()\n\nconsole.log(unsecuredJwt)\n```\n\nDecoding\n\n```js\nconst payload = jose.UnsecuredJWT.decode(unsecuredJwt, {\n  issuer: 'urn:example:issuer',\n  audience: 'urn:example:audience',\n})\n\nconsole.log(payload)\n```\n\n## Constructors\n\n### Constructor\n\n▸ **new UnsecuredJWT**(`payload?`): `UnsecuredJWT`\n\nUnsecuredJWT constructor\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `payload` | [`JWTPayload`](../../../types/interfaces/JWTPayload.md) | The JWT Claims Set object. Defaults to an empty object. |\n\n#### Returns\n\n`UnsecuredJWT`\n\n## Methods\n\n### decode()\n\n▸ `static` **decode**\\<`PayloadType`\\>(`jwt`, `options?`): [`UnsecuredResult`](../interfaces/UnsecuredResult.md)\\<`PayloadType`\\>\n\nDecodes an unsecured JWT.\n\n#### Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `PayloadType` | [`JWTPayload`](../../../types/interfaces/JWTPayload.md) |\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwt` | `string` | Unsecured JWT to decode the payload of. |\n| `options?` | [`JWTClaimVerificationOptions`](../../../types/interfaces/JWTClaimVerificationOptions.md) | JWT Claims Set validation options. |\n\n#### Returns\n\n[`UnsecuredResult`](../interfaces/UnsecuredResult.md)\\<`PayloadType`\\>\n\n***\n\n### encode()\n\n▸ **encode**(): `string`\n\nEncodes the Unsecured JWT.\n\n#### Returns\n\n`string`\n\n***\n\n### setAudience()\n\n▸ **setAudience**(`audience`): `this`\n\nSet the \"aud\" (Audience) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `audience` | `string` \\| `string`[] | \"aud\" (Audience) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setExpirationTime()\n\n▸ **setExpirationTime**(`input`): `this`\n\nSet the \"exp\" (Expiration Time) Claim.\n\n- If a `number` is passed as an argument it is used as the claim directly.\n- If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n  claim.\n- If a `string` is passed as an argument it is resolved to a time span, and then added to the\n  current unix timestamp and used as the claim.\n\nFormat used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\nday\".\n\nValid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n\"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n\"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\nalias for a year.\n\nIf the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\nsubtracted from the current unix timestamp. A \"from now\" suffix can also be used for\nreadability when adding to the current unix timestamp.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `input` | `string` \\| `number` \\| [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | \"exp\" (Expiration Time) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setIssuedAt()\n\n▸ **setIssuedAt**(`input?`): `this`\n\nSet the \"iat\" (Issued At) Claim.\n\n- If no argument is used the current unix timestamp is used as the claim.\n- If a `number` is passed as an argument it is used as the claim directly.\n- If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n  claim.\n- If a `string` is passed as an argument it is resolved to a time span, and then added to the\n  current unix timestamp and used as the claim.\n\nFormat used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\nday\".\n\nValid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n\"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n\"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\nalias for a year.\n\nIf the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\nsubtracted from the current unix timestamp. A \"from now\" suffix can also be used for\nreadability when adding to the current unix timestamp.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `input?` | `string` \\| `number` \\| [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | \"iat\" (Expiration Time) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setIssuer()\n\n▸ **setIssuer**(`issuer`): `this`\n\nSet the \"iss\" (Issuer) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `issuer` | `string` | \"Issuer\" Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setJti()\n\n▸ **setJti**(`jwtId`): `this`\n\nSet the \"jti\" (JWT ID) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwtId` | `string` | \"jti\" (JWT ID) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setNotBefore()\n\n▸ **setNotBefore**(`input`): `this`\n\nSet the \"nbf\" (Not Before) Claim.\n\n- If a `number` is passed as an argument it is used as the claim directly.\n- If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n  claim.\n- If a `string` is passed as an argument it is resolved to a time span, and then added to the\n  current unix timestamp and used as the claim.\n\nFormat used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\nday\".\n\nValid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n\"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n\"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\nalias for a year.\n\nIf the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\nsubtracted from the current unix timestamp. A \"from now\" suffix can also be used for\nreadability when adding to the current unix timestamp.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `input` | `string` \\| `number` \\| [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | \"nbf\" (Not Before) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setSubject()\n\n▸ **setSubject**(`subject`): `this`\n\nSet the \"sub\" (Subject) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `subject` | `string` | \"sub\" (Subject) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n"
  },
  {
    "path": "docs/jwt/unsecured/interfaces/UnsecuredResult.md",
    "content": "# Interface: UnsecuredResult\\<PayloadType\\>\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nResult of decoding an Unsecured JWT.\n\n## Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `PayloadType` | [`JWTPayload`](../../../types/interfaces/JWTPayload.md) |\n\n## Properties\n\n### header\n\n• **header**: [`JWSHeaderParameters`](../../../types/interfaces/JWSHeaderParameters.md)\n\n***\n\n### payload\n\n• **payload**: `PayloadType` & [`JWTPayload`](../../../types/interfaces/JWTPayload.md)\n"
  },
  {
    "path": "docs/jwt/verify/README.md",
    "content": "# jwt/verify\n\nJSON Web Token (JWT) Verification (JWT is in JWS format)\n\n## Interfaces\n\n- [JWTVerifyGetKey](interfaces/JWTVerifyGetKey.md)\n- [JWTVerifyOptions](interfaces/JWTVerifyOptions.md)\n\n## Functions\n\n- [jwtVerify](functions/jwtVerify.md)\n"
  },
  {
    "path": "docs/jwt/verify/functions/jwtVerify.md",
    "content": "# Function: jwtVerify()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n## Call Signature\n\n▸ **jwtVerify**\\<`PayloadType`\\>(`jwt`, `key`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`JWTVerifyResult`](../../../types/interfaces/JWTVerifyResult.md)\\<`PayloadType`\\>\\>\n\nVerifies the JWT format (to be a JWS Compact format), verifies the JWS signature, validates the\nJWT Claims Set.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/jwt/verify'`.\n\n### Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `PayloadType` | [`JWTPayload`](../../../types/interfaces/JWTPayload.md) |\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwt` | `string` \\| [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | JSON Web Token value (encoded as JWS). |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md) | Key to verify the JWT with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg). |\n| `options?` | [`JWTVerifyOptions`](../interfaces/JWTVerifyOptions.md) | JWT Decryption and JWT Claims Set validation options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`JWTVerifyResult`](../../../types/interfaces/JWTVerifyResult.md)\\<`PayloadType`\\>\\>\n\n### Examples\n\nUsage with a symmetric secret\n\n```js\nconst secret = new TextEncoder().encode(\n  'cc7e0d44fd473002f1c42167459001140ec6389b7353f8088f4d9a95f2f596f2',\n)\nconst jwt =\n  'eyJhbGciOiJIUzI1NiJ9.eyJ1cm46ZXhhbXBsZTpjbGFpbSI6dHJ1ZSwiaWF0IjoxNjY5MDU2MjMxLCJpc3MiOiJ1cm46ZXhhbXBsZTppc3N1ZXIiLCJhdWQiOiJ1cm46ZXhhbXBsZTphdWRpZW5jZSJ9.C4iSlLfAUMBq--wnC6VqD9gEOhwpRZpoRarE0m7KEnI'\n\nconst { payload, protectedHeader } = await jose.jwtVerify(jwt, secret, {\n  issuer: 'urn:example:issuer',\n  audience: 'urn:example:audience',\n})\n\nconsole.log(protectedHeader)\nconsole.log(payload)\n```\n\nUsage with a public SPKI encoded RSA key\n\n```js\nconst alg = 'RS256'\nconst spki = `-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwhYOFK2Ocbbpb/zVypi9\nSeKiNUqKQH0zTKN1+6fpCTu6ZalGI82s7XK3tan4dJt90ptUPKD2zvxqTzFNfx4H\nHHsrYCf2+FMLn1VTJfQazA2BvJqAwcpW1bqRUEty8tS/Yv4hRvWfQPcc2Gc3+/fQ\nOOW57zVy+rNoJc744kb30NjQxdGp03J2S3GLQu7oKtSDDPooQHD38PEMNnITf0pj\n+KgDPjymkMGoJlO3aKppsjfbt/AH6GGdRghYRLOUwQU+h+ofWHR3lbYiKtXPn5dN\n24kiHy61e3VAQ9/YAZlwXC/99GGtw/NpghFAuM4P1JDn0DppJldy3PGFC0GfBCZA\nSwIDAQAB\n-----END PUBLIC KEY-----`\nconst publicKey = await jose.importSPKI(spki, alg)\nconst jwt =\n  'eyJhbGciOiJSUzI1NiJ9.eyJ1cm46ZXhhbXBsZTpjbGFpbSI6dHJ1ZSwiaWF0IjoxNjY5MDU2NDg4LCJpc3MiOiJ1cm46ZXhhbXBsZTppc3N1ZXIiLCJhdWQiOiJ1cm46ZXhhbXBsZTphdWRpZW5jZSJ9.gXrPZ3yM_60dMXGE69dusbpzYASNA-XIOwsb5D5xYnSxyj6_D6OR_uR_1vqhUm4AxZxcrH1_-XJAve9HCw8az_QzHcN-nETt-v6stCsYrn6Bv1YOc-mSJRZ8ll57KVqLbCIbjKwerNX5r2_Qg2TwmJzQdRs-AQDhy-s_DlJd8ql6wR4n-kDZpar-pwIvz4fFIN0Fj57SXpAbLrV6Eo4Byzl0xFD8qEYEpBwjrMMfxCZXTlAVhAq6KCoGlDTwWuExps342-0UErEtyIqDnDGcrfNWiUsoo8j-29IpKd-w9-C388u-ChCxoHz--H8WmMSZzx3zTXsZ5lXLZ9IKfanDKg'\n\nconst { payload, protectedHeader } = await jose.jwtVerify(jwt, publicKey, {\n  issuer: 'urn:example:issuer',\n  audience: 'urn:example:audience',\n})\n\nconsole.log(protectedHeader)\nconsole.log(payload)\n```\n\nUsage with a public JWK encoded RSA key\n\n```js\nconst alg = 'RS256'\nconst jwk = {\n  kty: 'RSA',\n  n: 'whYOFK2Ocbbpb_zVypi9SeKiNUqKQH0zTKN1-6fpCTu6ZalGI82s7XK3tan4dJt90ptUPKD2zvxqTzFNfx4HHHsrYCf2-FMLn1VTJfQazA2BvJqAwcpW1bqRUEty8tS_Yv4hRvWfQPcc2Gc3-_fQOOW57zVy-rNoJc744kb30NjQxdGp03J2S3GLQu7oKtSDDPooQHD38PEMNnITf0pj-KgDPjymkMGoJlO3aKppsjfbt_AH6GGdRghYRLOUwQU-h-ofWHR3lbYiKtXPn5dN24kiHy61e3VAQ9_YAZlwXC_99GGtw_NpghFAuM4P1JDn0DppJldy3PGFC0GfBCZASw',\n  e: 'AQAB',\n}\nconst publicKey = await jose.importJWK(jwk, alg)\nconst jwt =\n  'eyJhbGciOiJSUzI1NiJ9.eyJ1cm46ZXhhbXBsZTpjbGFpbSI6dHJ1ZSwiaWF0IjoxNjY5MDU2NDg4LCJpc3MiOiJ1cm46ZXhhbXBsZTppc3N1ZXIiLCJhdWQiOiJ1cm46ZXhhbXBsZTphdWRpZW5jZSJ9.gXrPZ3yM_60dMXGE69dusbpzYASNA-XIOwsb5D5xYnSxyj6_D6OR_uR_1vqhUm4AxZxcrH1_-XJAve9HCw8az_QzHcN-nETt-v6stCsYrn6Bv1YOc-mSJRZ8ll57KVqLbCIbjKwerNX5r2_Qg2TwmJzQdRs-AQDhy-s_DlJd8ql6wR4n-kDZpar-pwIvz4fFIN0Fj57SXpAbLrV6Eo4Byzl0xFD8qEYEpBwjrMMfxCZXTlAVhAq6KCoGlDTwWuExps342-0UErEtyIqDnDGcrfNWiUsoo8j-29IpKd-w9-C388u-ChCxoHz--H8WmMSZzx3zTXsZ5lXLZ9IKfanDKg'\n\nconst { payload, protectedHeader } = await jose.jwtVerify(jwt, publicKey, {\n  issuer: 'urn:example:issuer',\n  audience: 'urn:example:audience',\n})\n\nconsole.log(protectedHeader)\nconsole.log(payload)\n```\n\n## Call Signature\n\n▸ **jwtVerify**\\<`PayloadType`\\>(`jwt`, `getKey`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`JWTVerifyResult`](../../../types/interfaces/JWTVerifyResult.md)\\<`PayloadType`\\> & [`ResolvedKey`](../../../types/interfaces/ResolvedKey.md)\\>\n\n### Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `PayloadType` | [`JWTPayload`](../../../types/interfaces/JWTPayload.md) |\n\n### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwt` | `string` \\| [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | JSON Web Token value (encoded as JWS). |\n| `getKey` | [`JWTVerifyGetKey`](../interfaces/JWTVerifyGetKey.md) | Function resolving a key to verify the JWT with. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg). |\n| `options?` | [`JWTVerifyOptions`](../interfaces/JWTVerifyOptions.md) | JWT Decryption and JWT Claims Set validation options. |\n\n### Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`JWTVerifyResult`](../../../types/interfaces/JWTVerifyResult.md)\\<`PayloadType`\\> & [`ResolvedKey`](../../../types/interfaces/ResolvedKey.md)\\>\n\n### Example\n\nUsage with a public JSON Web Key Set hosted on a remote URL\n\n```js\nconst JWKS = jose.createRemoteJWKSet(new URL('https://www.googleapis.com/oauth2/v3/certs'))\n\nconst { payload, protectedHeader } = await jose.jwtVerify(jwt, JWKS, {\n  issuer: 'urn:example:issuer',\n  audience: 'urn:example:audience',\n})\nconsole.log(protectedHeader)\nconsole.log(payload)\n```\n"
  },
  {
    "path": "docs/jwt/verify/interfaces/JWTVerifyGetKey.md",
    "content": "# Interface: JWTVerifyGetKey()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nInterface for JWT Verification dynamic key resolution. No token components have been verified at\nthe time of this function call.\n\n## See\n\n[createRemoteJWKSet](../../../jwks/remote/functions/createRemoteJWKSet.md) to verify using a remote JSON Web Key Set.\n\n▸ **JWTVerifyGetKey**(`protectedHeader`, `token`): [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md)\\>\n\nDynamic key resolution function. No token components have been verified at the time of this\nfunction call.\n\nIf a suitable key for the token cannot be matched, throw an error instead.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | [`JWTHeaderParameters`](../../../types/interfaces/JWTHeaderParameters.md) | JWE or JWS Protected Header. |\n| `token` | [`FlattenedJWSInput`](../../../types/interfaces/FlattenedJWSInput.md) | The consumed JWE or JWS token. |\n\n## Returns\n\n[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](../../../types/interfaces/JWK.md) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md)\\>\n"
  },
  {
    "path": "docs/jwt/verify/interfaces/JWTVerifyOptions.md",
    "content": "# Interface: JWTVerifyOptions\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nCombination of JWS Verification options and JWT Claims Set verification options.\n\n## Properties\n\n### algorithms?\n\n• `optional` **algorithms?**: `string`[]\n\nA list of accepted JWS \"alg\" (Algorithm) Header Parameter values. By default all \"alg\"\n(Algorithm) values applicable for the used key/secret are allowed.\n\n> [!NOTE]\\\n> Unsecured JWTs (`{ \"alg\": \"none\" }`) are never accepted by this API.\n\n***\n\n### audience?\n\n• `optional` **audience?**: `string` \\| `string`[]\n\nExpected JWT \"aud\" (Audience) Claim value(s).\n\nThis option makes the JWT \"aud\" (Audience) Claim presence required.\n\n***\n\n### clockTolerance?\n\n• `optional` **clockTolerance?**: `string` \\| `number`\n\nClock skew tolerance\n\n- In seconds when number (e.g. 5)\n- Resolved into a number of seconds when a string (e.g. \"5 seconds\", \"10 minutes\", \"2 hours\").\n\nUsed when validating the JWT \"nbf\" (Not Before) and \"exp\" (Expiration Time) claims, and when\nvalidating the \"iat\" (Issued At) claim if the [`maxTokenAge` option](../../../types/interfaces/JWTClaimVerificationOptions.md#maxtokenage) is set.\n\n***\n\n### crit?\n\n• `optional` **crit?**: `object`\n\nAn object with keys representing recognized \"crit\" (Critical) Header Parameter names. The value\nfor those is either `true` or `false`. `true` when the Header Parameter MUST be integrity\nprotected, `false` when it's irrelevant.\n\nThis makes the \"Extension Header Parameter \"...\" is not recognized\" error go away.\n\nUse this when a given JWS/JWT/JWE profile requires the use of proprietary non-registered \"crit\"\n(Critical) Header Parameters. This will only make sure the Header Parameter is syntactically\ncorrect when provided and that it is optionally integrity protected. It will not process the\nHeader Parameter in any way or reject the operation if it is missing. You MUST still verify the\nHeader Parameter was present and process it according to the profile's validation steps after\nthe operation succeeds.\n\nThe JWS extension Header Parameter `b64` is always recognized and processed properly. No other\nregistered Header Parameters that need this kind of default built-in treatment are currently\navailable.\n\n#### Index Signature\n\n\\[`propName`: `string`\\]: `boolean`\n\n***\n\n### currentDate?\n\n• `optional` **currentDate?**: [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date)\n\nDate to use when comparing NumericDate claims, defaults to `new Date()`.\n\n***\n\n### issuer?\n\n• `optional` **issuer?**: `string` \\| `string`[]\n\nExpected JWT \"iss\" (Issuer) Claim value(s).\n\nThis option makes the JWT \"iss\" (Issuer) Claim presence required.\n\n***\n\n### maxTokenAge?\n\n• `optional` **maxTokenAge?**: `string` \\| `number`\n\nMaximum time elapsed (in seconds) from the JWT \"iat\" (Issued At) Claim value.\n\n- In seconds when number (e.g. 5)\n- Resolved into a number of seconds when a string (e.g. \"5 seconds\", \"10 minutes\", \"2 hours\").\n\nThis option makes the JWT \"iat\" (Issued At) Claim presence required.\n\n***\n\n### requiredClaims?\n\n• `optional` **requiredClaims?**: `string`[]\n\nArray of required Claim Names that must be present in the JWT Claims Set. Default is that: if\nthe [`issuer` option](../../../types/interfaces/JWTClaimVerificationOptions.md#issuer) is set, then JWT \"iss\" (Issuer) Claim must be present; if the\n[`audience` option](../../../types/interfaces/JWTClaimVerificationOptions.md#audience) is set, then JWT \"aud\" (Audience) Claim must be present; if\nthe [`subject` option](../../../types/interfaces/JWTClaimVerificationOptions.md#subject) is set, then JWT \"sub\" (Subject) Claim must be present; if\nthe [`maxTokenAge` option](../../../types/interfaces/JWTClaimVerificationOptions.md#maxtokenage) is set, then JWT \"iat\" (Issued At) Claim must be\npresent.\n\n***\n\n### subject?\n\n• `optional` **subject?**: `string`\n\nExpected JWT \"sub\" (Subject) Claim value.\n\nThis option makes the JWT \"sub\" (Subject) Claim presence required.\n\n***\n\n### typ?\n\n• `optional` **typ?**: `string`\n\nExpected JWT \"typ\" (Type) Header Parameter value.\n\nThis option makes the JWT \"typ\" (Type) Header Parameter presence required.\n"
  },
  {
    "path": "docs/key/export/README.md",
    "content": "# key/export\n\nCryptographic key export functions\n\n## Functions\n\n- [exportJWK](functions/exportJWK.md)\n- [exportPKCS8](functions/exportPKCS8.md)\n- [exportSPKI](functions/exportSPKI.md)\n"
  },
  {
    "path": "docs/key/export/functions/exportJWK.md",
    "content": "# Function: exportJWK()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **exportJWK**(`key`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`JWK`](../../../types/interfaces/JWK.md)\\>\n\nExports a [CryptoKey](https://developer.mozilla.org/docs/Web/API/CryptoKey), [KeyObject](https://nodejs.org/api/crypto.html#class-keyobject), or [Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) to a JWK.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/key/export'`.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `key` | [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md) | Key to export as JWK. |\n\n## Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`JWK`](../../../types/interfaces/JWK.md)\\>\n\n## Example\n\n```js\nconst privateJwk = await jose.exportJWK(privateKey)\nconst publicJwk = await jose.exportJWK(publicKey)\n\nconsole.log(privateJwk)\nconsole.log(publicJwk)\n```\n"
  },
  {
    "path": "docs/key/export/functions/exportPKCS8.md",
    "content": "# Function: exportPKCS8()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **exportPKCS8**(`key`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n\nExports a private [CryptoKey](https://developer.mozilla.org/docs/Web/API/CryptoKey) or [KeyObject](https://nodejs.org/api/crypto.html#class-keyobject) to a PEM-encoded PKCS8 string format.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/key/export'`.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `key` | [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md) | Key to export to a PEM-encoded PKCS8 string format. |\n\n## Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n\n## Example\n\n```js\nconst pkcs8Pem = await jose.exportPKCS8(privateKey)\n\nconsole.log(pkcs8Pem)\n```\n"
  },
  {
    "path": "docs/key/export/functions/exportSPKI.md",
    "content": "# Function: exportSPKI()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **exportSPKI**(`key`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n\nExports a public [CryptoKey](https://developer.mozilla.org/docs/Web/API/CryptoKey) or [KeyObject](https://nodejs.org/api/crypto.html#class-keyobject) to a PEM-encoded SPKI string format.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/key/export'`.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `key` | [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`KeyObject`](../../../types/interfaces/KeyObject.md) | Key to export to a PEM-encoded SPKI string format. |\n\n## Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<`string`\\>\n\n## Example\n\n```js\nconst spkiPem = await jose.exportSPKI(publicKey)\n\nconsole.log(spkiPem)\n```\n"
  },
  {
    "path": "docs/key/generate_key_pair/README.md",
    "content": "# key/generate\\_key\\_pair\n\nAsymmetric key generation\n\n## Interfaces\n\n- [GenerateKeyPairOptions](interfaces/GenerateKeyPairOptions.md)\n- [GenerateKeyPairResult](interfaces/GenerateKeyPairResult.md)\n\n## Functions\n\n- [generateKeyPair](functions/generateKeyPair.md)\n"
  },
  {
    "path": "docs/key/generate_key_pair/functions/generateKeyPair.md",
    "content": "# Function: generateKeyPair()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **generateKeyPair**(`alg`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GenerateKeyPairResult`](../interfaces/GenerateKeyPairResult.md)\\>\n\nGenerates a private and a public key for a given JWA algorithm identifier. This can only generate\nasymmetric key pairs. For symmetric secrets use the `generateSecret` function.\n\n> [!NOTE]\\\n> The `privateKey` is generated with `extractable` set to `false` by default. See\n> [GenerateKeyPairOptions.extractable](../interfaces/GenerateKeyPairOptions.md#extractable) to generate an extractable `privateKey`.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/generate/keypair'`.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `alg` | `string` | JWA Algorithm Identifier to be used with the generated key pair. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210). |\n| `options?` | [`GenerateKeyPairOptions`](../interfaces/GenerateKeyPairOptions.md) | Additional options passed down to the key pair generation. |\n\n## Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`GenerateKeyPairResult`](../interfaces/GenerateKeyPairResult.md)\\>\n\n## Example\n\n```js\nconst { publicKey, privateKey } = await jose.generateKeyPair('PS256')\nconsole.log(publicKey)\nconsole.log(privateKey)\n```\n"
  },
  {
    "path": "docs/key/generate_key_pair/interfaces/GenerateKeyPairOptions.md",
    "content": "# Interface: GenerateKeyPairOptions\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAsymmetric key pair generation function options.\n\n## Properties\n\n### crv?\n\n• `optional` **crv?**: `string`\n\nThe EC \"crv\" (Curve) or OKP \"crv\" (Subtype of Key Pair) value to generate. The curve must be\nboth supported on the runtime as well as applicable for the given JWA algorithm identifier.\n\n***\n\n### extractable?\n\n• `optional` **extractable?**: `boolean`\n\nThe value to use as [SubtleCrypto.generateKey](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/generateKey) `extractable` argument. Default is false.\n\n#### Example\n\n```js\nconst { publicKey, privateKey } = await jose.generateKeyPair('PS256', {\n  extractable: true,\n})\nconsole.log(await jose.exportJWK(privateKey))\nconsole.log(await jose.exportPKCS8(privateKey))\n```\n\n***\n\n### modulusLength?\n\n• `optional` **modulusLength?**: `number`\n\nA hint for RSA algorithms to generate an RSA key of a given `modulusLength` (Key size in bits).\nJOSE requires 2048 bits or larger. Default is 2048.\n"
  },
  {
    "path": "docs/key/generate_key_pair/interfaces/GenerateKeyPairResult.md",
    "content": "# Interface: GenerateKeyPairResult\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAsymmetric key pair generation function result.\n\n## Properties\n\n### privateKey\n\n• **privateKey**: [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\n\nThe generated Private Key.\n\n***\n\n### publicKey\n\n• **publicKey**: [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\n\nPublic Key corresponding to the generated Private Key.\n"
  },
  {
    "path": "docs/key/generate_secret/README.md",
    "content": "# key/generate\\_secret\n\nSymmetric key generation\n\n## Interfaces\n\n- [GenerateSecretOptions](interfaces/GenerateSecretOptions.md)\n\n## Functions\n\n- [generateSecret](functions/generateSecret.md)\n"
  },
  {
    "path": "docs/key/generate_secret/functions/generateSecret.md",
    "content": "# Function: generateSecret()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **generateSecret**(`alg`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\nGenerates a symmetric secret key for a given JWA algorithm identifier.\n\n> [!NOTE]\\\n> The secret key is generated with `extractable` set to `false` by default.\n\n> [!NOTE]\\\n> Because A128CBC-HS256, A192CBC-HS384, and A256CBC-HS512 secrets cannot be represented as\n> [CryptoKey](https://developer.mozilla.org/docs/Web/API/CryptoKey) this method yields a [Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) for them instead.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/generate/secret'`.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `alg` | `string` | JWA Algorithm Identifier to be used with the generated secret. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210). |\n| `options?` | [`GenerateSecretOptions`](../interfaces/GenerateSecretOptions.md) | Additional options passed down to the secret generation. |\n\n## Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\n## Example\n\n```js\nconst secret = await jose.generateSecret('HS256')\nconsole.log(secret)\n```\n"
  },
  {
    "path": "docs/key/generate_secret/interfaces/GenerateSecretOptions.md",
    "content": "# Interface: GenerateSecretOptions\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nSecret generation function options.\n\n## Properties\n\n### extractable?\n\n• `optional` **extractable?**: `boolean`\n\nThe value to use as [SubtleCrypto.generateKey](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/generateKey) `extractable` argument. Default is false.\n\n> [!NOTE]\\\n> Because A128CBC-HS256, A192CBC-HS384, and A256CBC-HS512 secrets cannot be represented as\n> [CryptoKey](https://developer.mozilla.org/docs/Web/API/CryptoKey) this option has no effect for them.\n"
  },
  {
    "path": "docs/key/import/README.md",
    "content": "# key/import\n\nCryptographic key import functions\n\n## Interfaces\n\n- [KeyImportOptions](interfaces/KeyImportOptions.md)\n\n## Functions\n\n- [importJWK](functions/importJWK.md)\n- [importPKCS8](functions/importPKCS8.md)\n- [importSPKI](functions/importSPKI.md)\n- [importX509](functions/importX509.md)\n"
  },
  {
    "path": "docs/key/import/functions/importJWK.md",
    "content": "# Function: importJWK()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **importJWK**(`jwk`, `alg?`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\nImports a JWK to a [CryptoKey](https://developer.mozilla.org/docs/Web/API/CryptoKey). Either the JWK \"alg\" (Algorithm) Parameter, or the optional\n\"alg\" argument, must be present for asymmetric JSON Web Key imports.\n\n> [!NOTE]\\\n> The JSON Web Key parameters \"use\", \"key_ops\", and \"ext\" are also used in the [CryptoKey](https://developer.mozilla.org/docs/Web/API/CryptoKey)\n> import process.\n\n> [!NOTE]\\\n> Symmetric JSON Web Keys (i.e. `kty: \"oct\"`) yield back an [Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) instead of a\n> [CryptoKey](https://developer.mozilla.org/docs/Web/API/CryptoKey).\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/key/import'`.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwk` | [`JWK`](../../../types/interfaces/JWK.md) | JSON Web Key. |\n| `alg?` | `string` | JSON Web Algorithm identifier to be used with the imported key. Default is the \"alg\" property on the JWK. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210). |\n| `options?` | [`KeyImportOptions`](../interfaces/KeyImportOptions.md) | - |\n\n## Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\n## Example\n\n```js\nconst ecPublicKey = await jose.importJWK(\n  {\n    crv: 'P-256',\n    kty: 'EC',\n    x: 'ySK38C1jBdLwDsNWKzzBHqKYEE5Cgv-qjWvorUXk9fw',\n    y: '_LeQBw07cf5t57Iavn4j-BqJsAD1dpoz8gokd3sBsOo',\n  },\n  'ES256',\n)\n\nconst rsaPublicKey = await jose.importJWK(\n  {\n    kty: 'RSA',\n    e: 'AQAB',\n    n: '12oBZRhCiZFJLcPg59LkZZ9mdhSMTKAQZYq32k_ti5SBB6jerkh-WzOMAO664r_qyLkqHUSp3u5SbXtseZEpN3XPWGKSxjsy-1JyEFTdLSYe6f9gfrmxkUF_7DTpq0gn6rntP05g2-wFW50YO7mosfdslfrTJYWHFhJALabAeYirYD7-9kqq9ebfFMF4sRRELbv9oi36As6Q9B3Qb5_C1rAzqfao_PCsf9EPsTZsVVVkA5qoIAr47lo1ipfiBPxUCCNSdvkmDTYgvvRm6ZoMjFbvOtgyts55fXKdMWv7I9HMD5HwE9uW839PWA514qhbcIsXEYSFMPMV6fnlsiZvQQ',\n  },\n  'PS256',\n)\n```\n"
  },
  {
    "path": "docs/key/import/functions/importPKCS8.md",
    "content": "# Function: importPKCS8()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **importPKCS8**(`pkcs8`, `alg`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\nImports a PEM-encoded PKCS#8 string as a [CryptoKey](https://developer.mozilla.org/docs/Web/API/CryptoKey).\n\n> [!NOTE]\\\n> The OID id-RSASSA-PSS (1.2.840.113549.1.1.10) is not supported in\n> [Web Cryptography API](https://w3c.github.io/webcrypto/), use the OID rsaEncryption\n> (1.2.840.113549.1.1.1) instead for all RSA algorithms.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/key/import'`.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `pkcs8` | `string` | PEM-encoded PKCS#8 string |\n| `alg` | `string` | JSON Web Algorithm identifier to be used with the imported key. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210). |\n| `options?` | [`KeyImportOptions`](../interfaces/KeyImportOptions.md) | - |\n\n## Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\n## Example\n\n```js\nconst algorithm = 'ES256'\nconst pkcs8 = `-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgiyvo0X+VQ0yIrOaN\nnlrnUclopnvuuMfoc8HHly3505OhRANCAAQWUcdZ8uTSAsFuwtNy4KtsKqgeqYxg\nl6kwL5D4N3pEGYGIDjV69Sw0zAt43480WqJv7HCL0mQnyqFmSrxj8jMa\n-----END PRIVATE KEY-----`\nconst ecPrivateKey = await jose.importPKCS8(pkcs8, algorithm)\n```\n"
  },
  {
    "path": "docs/key/import/functions/importSPKI.md",
    "content": "# Function: importSPKI()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **importSPKI**(`spki`, `alg`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\nImports a PEM-encoded SPKI string as a [CryptoKey](https://developer.mozilla.org/docs/Web/API/CryptoKey).\n\n> [!NOTE]\\\n> The OID id-RSASSA-PSS (1.2.840.113549.1.1.10) is not supported in\n> [Web Cryptography API](https://w3c.github.io/webcrypto/), use the OID rsaEncryption\n> (1.2.840.113549.1.1.1) instead for all RSA algorithms.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/key/import'`.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `spki` | `string` | PEM-encoded SPKI string |\n| `alg` | `string` | JSON Web Algorithm identifier to be used with the imported key. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210). |\n| `options?` | [`KeyImportOptions`](../interfaces/KeyImportOptions.md) | - |\n\n## Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\n## Example\n\n```js\nconst algorithm = 'ES256'\nconst spki = `-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFlHHWfLk0gLBbsLTcuCrbCqoHqmM\nYJepMC+Q+Dd6RBmBiA41evUsNMwLeN+PNFqib+xwi9JkJ8qhZkq8Y/IzGg==\n-----END PUBLIC KEY-----`\nconst ecPublicKey = await jose.importSPKI(spki, algorithm)\n```\n"
  },
  {
    "path": "docs/key/import/functions/importX509.md",
    "content": "# Function: importX509()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **importX509**(`x509`, `alg`, `options?`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\nImports the SPKI from an X.509 string certificate as a [CryptoKey](https://developer.mozilla.org/docs/Web/API/CryptoKey).\n\n> [!NOTE]\\\n> The OID id-RSASSA-PSS (1.2.840.113549.1.1.10) is not supported in\n> [Web Cryptography API](https://w3c.github.io/webcrypto/), use the OID rsaEncryption\n> (1.2.840.113549.1.1.1) instead for all RSA algorithms.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/key/import'`.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `x509` | `string` | X.509 certificate string |\n| `alg` | `string` | JSON Web Algorithm identifier to be used with the imported key. See [Algorithm Key Requirements](https://github.com/panva/jose/issues/210). |\n| `options?` | [`KeyImportOptions`](../interfaces/KeyImportOptions.md) | - |\n\n## Returns\n\n[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\>\n\n## Example\n\n```js\nconst algorithm = 'ES256'\nconst x509 = `-----BEGIN CERTIFICATE-----\nMIIBXjCCAQSgAwIBAgIGAXvykuMKMAoGCCqGSM49BAMCMDYxNDAyBgNVBAMMK3Np\nQXBNOXpBdk1VaXhXVWVGaGtjZXg1NjJRRzFyQUhXaV96UlFQTVpQaG8wHhcNMjEw\nOTE3MDcwNTE3WhcNMjIwNzE0MDcwNTE3WjA2MTQwMgYDVQQDDCtzaUFwTTl6QXZN\nVWl4V1VlRmhrY2V4NTYyUUcxckFIV2lfelJRUE1aUGhvMFkwEwYHKoZIzj0CAQYI\nKoZIzj0DAQcDQgAE8PbPvCv5D5xBFHEZlBp/q5OEUymq7RIgWIi7tkl9aGSpYE35\nUH+kBKDnphJO3odpPZ5gvgKs2nwRWcrDnUjYLDAKBggqhkjOPQQDAgNIADBFAiEA\n1yyMTRe66MhEXID9+uVub7woMkNYd0LhSHwKSPMUUTkCIFQGsfm1ecXOpeGOufAh\nv+A1QWZMuTWqYt+uh/YSRNDn\n-----END CERTIFICATE-----`\nconst ecPublicKey = await jose.importX509(x509, algorithm)\n```\n"
  },
  {
    "path": "docs/key/import/interfaces/KeyImportOptions.md",
    "content": "# Interface: KeyImportOptions\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nKey Import Function options.\n\n## Properties\n\n### extractable?\n\n• `optional` **extractable?**: `boolean`\n\nThe value to use as [SubtleCrypto.importKey](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/importKey) `extractable` argument. Default is false for\nprivate keys, true otherwise.\n"
  },
  {
    "path": "docs/types/README.md",
    "content": "# types\n\n## Interfaces\n\n- [CompactDecryptResult](interfaces/CompactDecryptResult.md)\n- [CompactJWEHeaderParameters](interfaces/CompactJWEHeaderParameters.md)\n- [CompactJWSHeaderParameters](interfaces/CompactJWSHeaderParameters.md)\n- [CompactVerifyResult](interfaces/CompactVerifyResult.md)\n- [CritOption](interfaces/CritOption.md)\n- [DecryptOptions](interfaces/DecryptOptions.md)\n- [EncryptOptions](interfaces/EncryptOptions.md)\n- [FlattenedDecryptResult](interfaces/FlattenedDecryptResult.md)\n- [FlattenedJWE](interfaces/FlattenedJWE.md)\n- [FlattenedJWS](interfaces/FlattenedJWS.md)\n- [FlattenedJWSInput](interfaces/FlattenedJWSInput.md)\n- [FlattenedVerifyResult](interfaces/FlattenedVerifyResult.md)\n- [GeneralDecryptResult](interfaces/GeneralDecryptResult.md)\n- [GeneralJWE](interfaces/GeneralJWE.md)\n- [GeneralJWS](interfaces/GeneralJWS.md)\n- [GeneralJWSInput](interfaces/GeneralJWSInput.md)\n- [GeneralVerifyResult](interfaces/GeneralVerifyResult.md)\n- [GetKeyFunction](interfaces/GetKeyFunction.md)\n- [JoseHeaderParameters](interfaces/JoseHeaderParameters.md)\n- [JSONWebKeySet](interfaces/JSONWebKeySet.md)\n- [JWEHeaderParameters](interfaces/JWEHeaderParameters.md)\n- [JWEKeyManagementHeaderParameters](interfaces/JWEKeyManagementHeaderParameters.md)\n- [JWK](interfaces/JWK.md)\n- [JWK\\_AKP\\_Private](interfaces/JWK_AKP_Private.md)\n- [JWK\\_AKP\\_Public](interfaces/JWK_AKP_Public.md)\n- [JWK\\_EC\\_Private](interfaces/JWK_EC_Private.md)\n- [JWK\\_EC\\_Public](interfaces/JWK_EC_Public.md)\n- [JWK\\_oct](interfaces/JWK_oct.md)\n- [JWK\\_OKP\\_Private](interfaces/JWK_OKP_Private.md)\n- [JWK\\_OKP\\_Public](interfaces/JWK_OKP_Public.md)\n- [JWK\\_RSA\\_Private](interfaces/JWK_RSA_Private.md)\n- [JWK\\_RSA\\_Public](interfaces/JWK_RSA_Public.md)\n- [JWKParameters](interfaces/JWKParameters.md)\n- [JWSHeaderParameters](interfaces/JWSHeaderParameters.md)\n- [JWTClaimVerificationOptions](interfaces/JWTClaimVerificationOptions.md)\n- [JWTDecryptResult](interfaces/JWTDecryptResult.md)\n- [JWTHeaderParameters](interfaces/JWTHeaderParameters.md)\n- [JWTPayload](interfaces/JWTPayload.md)\n- [JWTVerifyResult](interfaces/JWTVerifyResult.md)\n- [KeyObject](interfaces/KeyObject.md)\n- [ProduceJWT](interfaces/ProduceJWT.md)\n- [ResolvedKey](interfaces/ResolvedKey.md)\n- [SignOptions](interfaces/SignOptions.md)\n- [VerifyOptions](interfaces/VerifyOptions.md)\n\n## Type Aliases\n\n- [CryptoKey](type-aliases/CryptoKey.md)\n"
  },
  {
    "path": "docs/types/interfaces/CompactDecryptResult.md",
    "content": "# Interface: CompactDecryptResult\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nCompact JWE decryption result\n\n## Properties\n\n### plaintext\n\n• **plaintext**: [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\nPlaintext.\n\n***\n\n### protectedHeader\n\n• **protectedHeader**: [`CompactJWEHeaderParameters`](CompactJWEHeaderParameters.md)\n\nJWE Protected Header.\n"
  },
  {
    "path": "docs/types/interfaces/CompactJWEHeaderParameters.md",
    "content": "# Interface: CompactJWEHeaderParameters\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nRecognized Compact JWE Header Parameters, any other Header Members may also be present.\n\n## Indexable\n\n> \\[`propName`: `string`\\]: `unknown`\n\nAny other JWE Header member.\n\n## Properties\n\n### alg\n\n• **alg**: `string`\n\nJWE \"alg\" (Algorithm) Header Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg)\n\n***\n\n### enc\n\n• **enc**: `string`\n\nJWE \"enc\" (Encryption Algorithm) Header Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg)\n\n***\n\n### crit?\n\n• `optional` **crit?**: `string`[]\n\nJWE \"crit\" (Critical) Header Parameter\n\n***\n\n### cty?\n\n• `optional` **cty?**: `string`\n\n\"cty\" (Content Type) Header Parameter\n\n***\n\n### jku?\n\n• `optional` **jku?**: `string`\n\n\"jku\" (JWK Set URL) Header Parameter\n\n***\n\n### jwk?\n\n• `optional` **jwk?**: [`Pick`](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys)\\<[`JWK`](JWK.md), `\"x\"` \\| `\"y\"` \\| `\"crv\"` \\| `\"e\"` \\| `\"n\"` \\| `\"pub\"` \\| `\"kty\"` \\| `\"alg\"`\\>\n\n\"jwk\" (JSON Web Key) Header Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\n\"kid\" (Key ID) Header Parameter\n\n***\n\n### typ?\n\n• `optional` **typ?**: `string`\n\n\"typ\" (Type) Header Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\n\"x5c\" (X.509 Certificate Chain) Header Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\n\"x5t\" (X.509 Certificate SHA-1 Thumbprint) Header Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\n\"x5u\" (X.509 URL) Header Parameter\n\n***\n\n### zip?\n\n• `optional` **zip?**: `string`\n\nJWE \"zip\" (Compression Algorithm) Header Parameter.\n\nThe only supported value is `\"DEF\"` (DEFLATE). Requires the `CompressionStream` /\n`DecompressionStream` APIs to be available in the runtime.\n\n#### See\n\n[JWE \"zip\" Header Parameter](https://www.rfc-editor.org/rfc/rfc7516#section-4.1.3)\n"
  },
  {
    "path": "docs/types/interfaces/CompactJWSHeaderParameters.md",
    "content": "# Interface: CompactJWSHeaderParameters\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nRecognized Compact JWS Header Parameters, any other Header Members may also be present.\n\n## Indexable\n\n> \\[`propName`: `string`\\]: `unknown`\n\nAny other JWS Header member.\n\n## Properties\n\n### alg\n\n• **alg**: `string`\n\nJWS \"alg\" (Algorithm) Header Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg)\n\n***\n\n### b64?\n\n• `optional` **b64?**: `boolean`\n\nThis JWS Extension Header Parameter modifies the JWS Payload representation and the JWS Signing\nInput computation as per [RFC7797](https://www.rfc-editor.org/rfc/rfc7797).\n\n***\n\n### crit?\n\n• `optional` **crit?**: `string`[]\n\nJWS \"crit\" (Critical) Header Parameter\n\n***\n\n### cty?\n\n• `optional` **cty?**: `string`\n\n\"cty\" (Content Type) Header Parameter\n\n***\n\n### jku?\n\n• `optional` **jku?**: `string`\n\n\"jku\" (JWK Set URL) Header Parameter\n\n***\n\n### jwk?\n\n• `optional` **jwk?**: [`Pick`](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys)\\<[`JWK`](JWK.md), `\"x\"` \\| `\"y\"` \\| `\"crv\"` \\| `\"e\"` \\| `\"n\"` \\| `\"pub\"` \\| `\"kty\"` \\| `\"alg\"`\\>\n\n\"jwk\" (JSON Web Key) Header Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\n\"kid\" (Key ID) Header Parameter\n\n***\n\n### typ?\n\n• `optional` **typ?**: `string`\n\n\"typ\" (Type) Header Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\n\"x5c\" (X.509 Certificate Chain) Header Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\n\"x5t\" (X.509 Certificate SHA-1 Thumbprint) Header Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\n\"x5u\" (X.509 URL) Header Parameter\n"
  },
  {
    "path": "docs/types/interfaces/CompactVerifyResult.md",
    "content": "# Interface: CompactVerifyResult\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nCompact JWS verification result\n\n## Properties\n\n### payload\n\n• **payload**: [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\nJWS Payload.\n\n***\n\n### protectedHeader\n\n• **protectedHeader**: [`CompactJWSHeaderParameters`](CompactJWSHeaderParameters.md)\n\nJWS Protected Header.\n"
  },
  {
    "path": "docs/types/interfaces/CritOption.md",
    "content": "# Interface: CritOption\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nShared Interface with a \"crit\" property for all sign, verify, encrypt and decrypt operations.\n\n## Properties\n\n### crit?\n\n• `optional` **crit?**: `object`\n\nAn object with keys representing recognized \"crit\" (Critical) Header Parameter names. The value\nfor those is either `true` or `false`. `true` when the Header Parameter MUST be integrity\nprotected, `false` when it's irrelevant.\n\nThis makes the \"Extension Header Parameter \"...\" is not recognized\" error go away.\n\nUse this when a given JWS/JWT/JWE profile requires the use of proprietary non-registered \"crit\"\n(Critical) Header Parameters. This will only make sure the Header Parameter is syntactically\ncorrect when provided and that it is optionally integrity protected. It will not process the\nHeader Parameter in any way or reject the operation if it is missing. You MUST still verify the\nHeader Parameter was present and process it according to the profile's validation steps after\nthe operation succeeds.\n\nThe JWS extension Header Parameter `b64` is always recognized and processed properly. No other\nregistered Header Parameters that need this kind of default built-in treatment are currently\navailable.\n\n#### Index Signature\n\n\\[`propName`: `string`\\]: `boolean`\n"
  },
  {
    "path": "docs/types/interfaces/DecryptOptions.md",
    "content": "# Interface: DecryptOptions\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nJWE Decryption options.\n\n## Properties\n\n### contentEncryptionAlgorithms?\n\n• `optional` **contentEncryptionAlgorithms?**: `string`[]\n\nA list of accepted JWE \"enc\" (Encryption Algorithm) Header Parameter values. By default all\n\"enc\" (Encryption Algorithm) values applicable for the used key/secret are allowed.\n\n***\n\n### crit?\n\n• `optional` **crit?**: `object`\n\nAn object with keys representing recognized \"crit\" (Critical) Header Parameter names. The value\nfor those is either `true` or `false`. `true` when the Header Parameter MUST be integrity\nprotected, `false` when it's irrelevant.\n\nThis makes the \"Extension Header Parameter \"...\" is not recognized\" error go away.\n\nUse this when a given JWS/JWT/JWE profile requires the use of proprietary non-registered \"crit\"\n(Critical) Header Parameters. This will only make sure the Header Parameter is syntactically\ncorrect when provided and that it is optionally integrity protected. It will not process the\nHeader Parameter in any way or reject the operation if it is missing. You MUST still verify the\nHeader Parameter was present and process it according to the profile's validation steps after\nthe operation succeeds.\n\nThe JWS extension Header Parameter `b64` is always recognized and processed properly. No other\nregistered Header Parameters that need this kind of default built-in treatment are currently\navailable.\n\n#### Index Signature\n\n\\[`propName`: `string`\\]: `boolean`\n\n***\n\n### keyManagementAlgorithms?\n\n• `optional` **keyManagementAlgorithms?**: `string`[]\n\nA list of accepted JWE \"alg\" (Algorithm) Header Parameter values. By default all \"alg\"\n(Algorithm) Header Parameter values applicable for the used key/secret are allowed except for\nall PBES2 Key Management Algorithms, these need to be explicitly allowed using this option.\n\n***\n\n### maxDecompressedLength?\n\n• `optional` **maxDecompressedLength?**: `number`\n\nMaximum allowed size (in bytes) of the decompressed plaintext when the JWE `\"zip\"` (Compression\nAlgorithm) Header Parameter is present. By default this value is set to 250000 (250 KB). The\nvalue must be `0`, a positive safe integer, or `Infinity`.\n\nSet to `0` to reject all compressed JWEs during decryption.\n\nSet to `Infinity` to disable the decompressed size limit.\n\n***\n\n### maxPBES2Count?\n\n• `optional` **maxPBES2Count?**: `number`\n\n(PBES2 Key Management Algorithms only) Maximum allowed \"p2c\" (PBES2 Count) Header Parameter\nvalue. The PBKDF2 iteration count defines the algorithm's computational expense. By default\nthis value is set to 10000.\n"
  },
  {
    "path": "docs/types/interfaces/EncryptOptions.md",
    "content": "# Interface: EncryptOptions\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nJWE Encryption options.\n\n## Properties\n\n### crit?\n\n• `optional` **crit?**: `object`\n\nAn object with keys representing recognized \"crit\" (Critical) Header Parameter names. The value\nfor those is either `true` or `false`. `true` when the Header Parameter MUST be integrity\nprotected, `false` when it's irrelevant.\n\nThis makes the \"Extension Header Parameter \"...\" is not recognized\" error go away.\n\nUse this when a given JWS/JWT/JWE profile requires the use of proprietary non-registered \"crit\"\n(Critical) Header Parameters. This will only make sure the Header Parameter is syntactically\ncorrect when provided and that it is optionally integrity protected. It will not process the\nHeader Parameter in any way or reject the operation if it is missing. You MUST still verify the\nHeader Parameter was present and process it according to the profile's validation steps after\nthe operation succeeds.\n\nThe JWS extension Header Parameter `b64` is always recognized and processed properly. No other\nregistered Header Parameters that need this kind of default built-in treatment are currently\navailable.\n\n#### Index Signature\n\n\\[`propName`: `string`\\]: `boolean`\n"
  },
  {
    "path": "docs/types/interfaces/FlattenedDecryptResult.md",
    "content": "# Interface: FlattenedDecryptResult\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nFlattened JWE JSON Serialization Syntax decryption result\n\n## Properties\n\n### plaintext\n\n• **plaintext**: [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\nPlaintext.\n\n***\n\n### additionalAuthenticatedData?\n\n• `optional` **additionalAuthenticatedData?**: [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\nJWE AAD.\n\n***\n\n### protectedHeader?\n\n• `optional` **protectedHeader?**: [`JWEHeaderParameters`](JWEHeaderParameters.md)\n\nJWE Protected Header.\n\n***\n\n### sharedUnprotectedHeader?\n\n• `optional` **sharedUnprotectedHeader?**: [`JWEHeaderParameters`](JWEHeaderParameters.md)\n\nJWE Shared Unprotected Header.\n\n***\n\n### unprotectedHeader?\n\n• `optional` **unprotectedHeader?**: [`JWEHeaderParameters`](JWEHeaderParameters.md)\n\nJWE Per-Recipient Unprotected Header.\n"
  },
  {
    "path": "docs/types/interfaces/FlattenedJWE.md",
    "content": "# Interface: FlattenedJWE\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nFlattened JWE JSON Serialization Syntax token.\n\n## Properties\n\n### ciphertext\n\n• **ciphertext**: `string`\n\nThe \"ciphertext\" member MUST be present and contain the value BASE64URL(JWE Ciphertext).\n\n***\n\n### aad?\n\n• `optional` **aad?**: `string`\n\nThe \"aad\" member MUST be present and contain the value BASE64URL(JWE AAD)) when the JWE AAD\nvalue is non-empty; otherwise, it MUST be absent. A JWE AAD value can be included to supply a\nbase64url-encoded value to be integrity protected but not encrypted.\n\n***\n\n### encrypted\\_key?\n\n• `optional` **encrypted\\_key?**: `string`\n\nThe \"encrypted_key\" member MUST be present and contain the value BASE64URL(JWE Encrypted Key)\nwhen the JWE Encrypted Key value is non-empty; otherwise, it MUST be absent.\n\n***\n\n### header?\n\n• `optional` **header?**: [`JWEHeaderParameters`](JWEHeaderParameters.md)\n\nThe \"header\" member MUST be present and contain the value JWE Per- Recipient Unprotected Header\nwhen the JWE Per-Recipient Unprotected Header value is non-empty; otherwise, it MUST be absent.\nThis value is represented as an unencoded JSON object, rather than as a string. These Header\nParameter values are not integrity protected.\n\n***\n\n### iv?\n\n• `optional` **iv?**: `string`\n\nThe \"iv\" member MUST be present and contain the value BASE64URL(JWE Initialization Vector) when\nthe JWE Initialization Vector value is non-empty; otherwise, it MUST be absent.\n\n***\n\n### protected?\n\n• `optional` **protected?**: `string`\n\nThe \"protected\" member MUST be present and contain the value BASE64URL(UTF8(JWE Protected\nHeader)) when the JWE Protected Header value is non-empty; otherwise, it MUST be absent. These\nHeader Parameter values are integrity protected.\n\n***\n\n### tag?\n\n• `optional` **tag?**: `string`\n\nThe \"tag\" member MUST be present and contain the value BASE64URL(JWE Authentication Tag) when\nthe JWE Authentication Tag value is non-empty; otherwise, it MUST be absent.\n\n***\n\n### unprotected?\n\n• `optional` **unprotected?**: [`JWEHeaderParameters`](JWEHeaderParameters.md)\n\nThe \"unprotected\" member MUST be present and contain the value JWE Shared Unprotected Header\nwhen the JWE Shared Unprotected Header value is non-empty; otherwise, it MUST be absent. This\nvalue is represented as an unencoded JSON object, rather than as a string. These Header\nParameter values are not integrity protected.\n"
  },
  {
    "path": "docs/types/interfaces/FlattenedJWS.md",
    "content": "# Interface: FlattenedJWS\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nFlattened JWS JSON Serialization Syntax token. Payload is returned as an empty string when JWS\nUnencoded Payload ([RFC7797](https://www.rfc-editor.org/rfc/rfc7797)) is used.\n\n## Properties\n\n### payload\n\n• **payload**: `string`\n\nThe \"payload\" member MUST be present and contain the value BASE64URL(JWS Payload). When RFC7797\n\"b64\": false is used the value passed may also be a [Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array).\n\n***\n\n### signature\n\n• **signature**: `string`\n\nThe \"signature\" member MUST be present and contain the value BASE64URL(JWS Signature).\n\n***\n\n### header?\n\n• `optional` **header?**: [`JWSHeaderParameters`](JWSHeaderParameters.md)\n\nThe \"header\" member MUST be present and contain the value JWS Unprotected Header when the JWS\nUnprotected Header value is non- empty; otherwise, it MUST be absent. This value is represented\nas an unencoded JSON object, rather than as a string. These Header Parameter values are not\nintegrity protected.\n\n***\n\n### protected?\n\n• `optional` **protected?**: `string`\n\nThe \"protected\" member MUST be present and contain the value BASE64URL(UTF8(JWS Protected\nHeader)) when the JWS Protected Header value is non-empty; otherwise, it MUST be absent. These\nHeader Parameter values are integrity protected.\n"
  },
  {
    "path": "docs/types/interfaces/FlattenedJWSInput.md",
    "content": "# Interface: FlattenedJWSInput\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nFlattened JWS definition for verify function inputs, allows payload as [Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) for\ndetached signature validation.\n\n## Properties\n\n### payload\n\n• **payload**: `string` \\| [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\nThe \"payload\" member MUST be present and contain the value BASE64URL(JWS Payload). When RFC7797\n\"b64\": false is used the value passed may also be a [Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array).\n\n***\n\n### signature\n\n• **signature**: `string`\n\nThe \"signature\" member MUST be present and contain the value BASE64URL(JWS Signature).\n\n***\n\n### header?\n\n• `optional` **header?**: [`JWSHeaderParameters`](JWSHeaderParameters.md)\n\nThe \"header\" member MUST be present and contain the value JWS Unprotected Header when the JWS\nUnprotected Header value is non- empty; otherwise, it MUST be absent. This value is represented\nas an unencoded JSON object, rather than as a string. These Header Parameter values are not\nintegrity protected.\n\n***\n\n### protected?\n\n• `optional` **protected?**: `string`\n\nThe \"protected\" member MUST be present and contain the value BASE64URL(UTF8(JWS Protected\nHeader)) when the JWS Protected Header value is non-empty; otherwise, it MUST be absent. These\nHeader Parameter values are integrity protected.\n"
  },
  {
    "path": "docs/types/interfaces/FlattenedVerifyResult.md",
    "content": "# Interface: FlattenedVerifyResult\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nFlattened JWS JSON Serialization Syntax verification result\n\n## Properties\n\n### payload\n\n• **payload**: [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\nJWS Payload.\n\n***\n\n### protectedHeader?\n\n• `optional` **protectedHeader?**: [`JWSHeaderParameters`](JWSHeaderParameters.md)\n\nJWS Protected Header.\n\n***\n\n### unprotectedHeader?\n\n• `optional` **unprotectedHeader?**: [`JWSHeaderParameters`](JWSHeaderParameters.md)\n\nJWS Unprotected Header.\n"
  },
  {
    "path": "docs/types/interfaces/GeneralDecryptResult.md",
    "content": "# Interface: GeneralDecryptResult\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nGeneral JWE JSON Serialization Syntax decryption result\n\n## Properties\n\n### plaintext\n\n• **plaintext**: [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\nPlaintext.\n\n***\n\n### additionalAuthenticatedData?\n\n• `optional` **additionalAuthenticatedData?**: [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\nJWE AAD.\n\n***\n\n### protectedHeader?\n\n• `optional` **protectedHeader?**: [`JWEHeaderParameters`](JWEHeaderParameters.md)\n\nJWE Protected Header.\n\n***\n\n### sharedUnprotectedHeader?\n\n• `optional` **sharedUnprotectedHeader?**: [`JWEHeaderParameters`](JWEHeaderParameters.md)\n\nJWE Shared Unprotected Header.\n\n***\n\n### unprotectedHeader?\n\n• `optional` **unprotectedHeader?**: [`JWEHeaderParameters`](JWEHeaderParameters.md)\n\nJWE Per-Recipient Unprotected Header.\n"
  },
  {
    "path": "docs/types/interfaces/GeneralJWE.md",
    "content": "# Interface: GeneralJWE\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nGeneral JWE JSON Serialization Syntax token.\n\n## Properties\n\n### ciphertext\n\n• **ciphertext**: `string`\n\nThe \"ciphertext\" member MUST be present and contain the value BASE64URL(JWE Ciphertext).\n\n***\n\n### recipients\n\n• **recipients**: [`Pick`](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys)\\<[`FlattenedJWE`](FlattenedJWE.md), `\"header\"` \\| `\"encrypted_key\"`\\>[]\n\n***\n\n### aad?\n\n• `optional` **aad?**: `string`\n\nThe \"aad\" member MUST be present and contain the value BASE64URL(JWE AAD)) when the JWE AAD\nvalue is non-empty; otherwise, it MUST be absent. A JWE AAD value can be included to supply a\nbase64url-encoded value to be integrity protected but not encrypted.\n\n***\n\n### iv?\n\n• `optional` **iv?**: `string`\n\nThe \"iv\" member MUST be present and contain the value BASE64URL(JWE Initialization Vector) when\nthe JWE Initialization Vector value is non-empty; otherwise, it MUST be absent.\n\n***\n\n### protected?\n\n• `optional` **protected?**: `string`\n\nThe \"protected\" member MUST be present and contain the value BASE64URL(UTF8(JWE Protected\nHeader)) when the JWE Protected Header value is non-empty; otherwise, it MUST be absent. These\nHeader Parameter values are integrity protected.\n\n***\n\n### tag?\n\n• `optional` **tag?**: `string`\n\nThe \"tag\" member MUST be present and contain the value BASE64URL(JWE Authentication Tag) when\nthe JWE Authentication Tag value is non-empty; otherwise, it MUST be absent.\n\n***\n\n### unprotected?\n\n• `optional` **unprotected?**: [`JWEHeaderParameters`](JWEHeaderParameters.md)\n\nThe \"unprotected\" member MUST be present and contain the value JWE Shared Unprotected Header\nwhen the JWE Shared Unprotected Header value is non-empty; otherwise, it MUST be absent. This\nvalue is represented as an unencoded JSON object, rather than as a string. These Header\nParameter values are not integrity protected.\n"
  },
  {
    "path": "docs/types/interfaces/GeneralJWS.md",
    "content": "# Interface: GeneralJWS\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nGeneral JWS JSON Serialization Syntax token. Payload is returned as an empty string when JWS\nUnencoded Payload ([RFC7797](https://www.rfc-editor.org/rfc/rfc7797)) is used.\n\n## Properties\n\n### payload\n\n• **payload**: `string`\n\n***\n\n### signatures\n\n• **signatures**: [`Omit`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys)\\<[`FlattenedJWSInput`](FlattenedJWSInput.md), `\"payload\"`\\>[]\n"
  },
  {
    "path": "docs/types/interfaces/GeneralJWSInput.md",
    "content": "# Interface: GeneralJWSInput\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nGeneral JWS definition for verify function inputs, allows payload as [Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) for\ndetached signature validation.\n\n## Properties\n\n### payload\n\n• **payload**: `string` \\| [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\nThe \"payload\" member MUST be present and contain the value BASE64URL(JWS Payload). When when\nJWS Unencoded Payload ([RFC7797](https://www.rfc-editor.org/rfc/rfc7797)) \"b64\": false is\nused the value passed may also be a [Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array).\n\n***\n\n### signatures\n\n• **signatures**: [`Omit`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys)\\<[`FlattenedJWSInput`](FlattenedJWSInput.md), `\"payload\"`\\>[]\n\nThe \"signatures\" member value MUST be an array of JSON objects. Each object represents a\nsignature or MAC over the JWS Payload and the JWS Protected Header.\n"
  },
  {
    "path": "docs/types/interfaces/GeneralVerifyResult.md",
    "content": "# Interface: GeneralVerifyResult\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nGeneral JWS JSON Serialization Syntax verification result\n\n## Properties\n\n### payload\n\n• **payload**: [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\nJWS Payload.\n\n***\n\n### protectedHeader?\n\n• `optional` **protectedHeader?**: [`JWSHeaderParameters`](JWSHeaderParameters.md)\n\nJWS Protected Header.\n\n***\n\n### unprotectedHeader?\n\n• `optional` **unprotectedHeader?**: [`JWSHeaderParameters`](JWSHeaderParameters.md)\n\nJWS Unprotected Header.\n"
  },
  {
    "path": "docs/types/interfaces/GetKeyFunction.md",
    "content": "# Interface: GetKeyFunction()\\<IProtectedHeader, IToken\\>\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nGeneric Interface for consuming operations dynamic key resolution.\n\n## Type Parameters\n\n| Type Parameter | Description |\n| ------ | ------ |\n| `IProtectedHeader` | Type definition of the JWE or JWS Protected Header. |\n| `IToken` | Type definition of the consumed JWE or JWS token. |\n\n▸ **GetKeyFunction**(`protectedHeader`, `token`): [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](JWK.md) \\| [`KeyObject`](KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](JWK.md) \\| [`KeyObject`](KeyObject.md)\\>\n\nDynamic key resolution function. No token components have been verified at the time of this\nfunction call.\n\nIf a suitable key for the token cannot be matched, throw an error instead.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `protectedHeader` | `IProtectedHeader` | JWE or JWS Protected Header. |\n| `token` | `IToken` | The consumed JWE or JWS token. |\n\n## Returns\n\n[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](JWK.md) \\| [`KeyObject`](KeyObject.md) \\| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`JWK`](JWK.md) \\| [`KeyObject`](KeyObject.md)\\>\n"
  },
  {
    "path": "docs/types/interfaces/JSONWebKeySet.md",
    "content": "# Interface: JSONWebKeySet\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nJSON Web Key Set\n\n## Properties\n\n### keys\n\n• **keys**: [`JWK`](JWK.md)[]\n"
  },
  {
    "path": "docs/types/interfaces/JWEHeaderParameters.md",
    "content": "# Interface: JWEHeaderParameters\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nRecognized JWE Header Parameters, any other Header members may also be present.\n\n## Indexable\n\n> \\[`propName`: `string`\\]: `unknown`\n\nAny other JWE Header member.\n\n## Properties\n\n### alg?\n\n• `optional` **alg?**: `string`\n\nJWE \"alg\" (Algorithm) Header Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg)\n\n***\n\n### crit?\n\n• `optional` **crit?**: `string`[]\n\nJWE \"crit\" (Critical) Header Parameter\n\n***\n\n### cty?\n\n• `optional` **cty?**: `string`\n\n\"cty\" (Content Type) Header Parameter\n\n***\n\n### enc?\n\n• `optional` **enc?**: `string`\n\nJWE \"enc\" (Encryption Algorithm) Header Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jwe-alg)\n\n***\n\n### jku?\n\n• `optional` **jku?**: `string`\n\n\"jku\" (JWK Set URL) Header Parameter\n\n***\n\n### jwk?\n\n• `optional` **jwk?**: [`Pick`](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys)\\<[`JWK`](JWK.md), `\"x\"` \\| `\"y\"` \\| `\"crv\"` \\| `\"e\"` \\| `\"n\"` \\| `\"pub\"` \\| `\"kty\"` \\| `\"alg\"`\\>\n\n\"jwk\" (JSON Web Key) Header Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\n\"kid\" (Key ID) Header Parameter\n\n***\n\n### typ?\n\n• `optional` **typ?**: `string`\n\n\"typ\" (Type) Header Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\n\"x5c\" (X.509 Certificate Chain) Header Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\n\"x5t\" (X.509 Certificate SHA-1 Thumbprint) Header Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\n\"x5u\" (X.509 URL) Header Parameter\n\n***\n\n### zip?\n\n• `optional` **zip?**: `string`\n\nJWE \"zip\" (Compression Algorithm) Header Parameter.\n\nThe only supported value is `\"DEF\"` (DEFLATE). Requires the `CompressionStream` /\n`DecompressionStream` APIs to be available in the runtime.\n\n#### See\n\n[JWE \"zip\" Header Parameter](https://www.rfc-editor.org/rfc/rfc7516#section-4.1.3)\n"
  },
  {
    "path": "docs/types/interfaces/JWEKeyManagementHeaderParameters.md",
    "content": "# Interface: JWEKeyManagementHeaderParameters\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nRecognized JWE Key Management-related Header Parameters.\n\n## Properties\n\n### apu?\n\n• `optional` **apu?**: [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\nECDH-ES \"apu\" (Agreement PartyUInfo). This will be used as a JOSE Header Parameter and will be\nused in ECDH's ConcatKDF.\n\n***\n\n### apv?\n\n• `optional` **apv?**: [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\nECDH-ES \"apv\" (Agreement PartyVInfo). This will be used as a JOSE Header Parameter and will be\nused in ECDH's ConcatKDF.\n\n***\n\n### ~~epk?~~\n\n• `optional` **epk?**: [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) \\| [`KeyObject`](KeyObject.md)\n\n#### Deprecated\n\nYou should not use this parameter. It is only intended for testing and vector\n  validation purposes.\n\n***\n\n### ~~iv?~~\n\n• `optional` **iv?**: [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\n#### Deprecated\n\nYou should not use this parameter. It is only intended for testing and vector\n  validation purposes.\n\n***\n\n### ~~p2c?~~\n\n• `optional` **p2c?**: `number`\n\n#### Deprecated\n\nYou should not use this parameter. It is only intended for testing and vector\n  validation purposes.\n\n***\n\n### ~~p2s?~~\n\n• `optional` **p2s?**: [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\n#### Deprecated\n\nYou should not use this parameter. It is only intended for testing and vector\n  validation purposes.\n"
  },
  {
    "path": "docs/types/interfaces/JWK.md",
    "content": "# Interface: JWK\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nJSON Web Key ([JWK](https://www.rfc-editor.org/rfc/rfc7517)). \"RSA\", \"EC\", \"OKP\", \"AKP\", and\n\"oct\" key types are supported.\n\n## See\n\n - [JWK\\_AKP\\_Public](JWK_AKP_Public.md)\n - [JWK\\_AKP\\_Private](JWK_AKP_Private.md)\n - [JWK\\_OKP\\_Public](JWK_OKP_Public.md)\n - [JWK\\_OKP\\_Private](JWK_OKP_Private.md)\n - [JWK\\_EC\\_Public](JWK_EC_Public.md)\n - [JWK\\_EC\\_Private](JWK_EC_Private.md)\n - [JWK\\_RSA\\_Public](JWK_RSA_Public.md)\n - [JWK\\_RSA\\_Private](JWK_RSA_Private.md)\n - [JWK\\_oct](JWK_oct.md)\n\n## Properties\n\n### alg?\n\n• `optional` **alg?**: `string`\n\nJWK \"alg\" (Algorithm) Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210)\n\n***\n\n### crv?\n\n• `optional` **crv?**: `string`\n\n- EC JWK \"crv\" (Curve) Parameter\n- OKP JWK \"crv\" (The Subtype of Key Pair) Parameter\n\n***\n\n### d?\n\n• `optional` **d?**: `string`\n\n- Private RSA JWK \"d\" (Private Exponent) Parameter\n- Private EC JWK \"d\" (ECC Private Key) Parameter\n- Private OKP JWK \"d\" (The Private Key) Parameter\n\n***\n\n### dp?\n\n• `optional` **dp?**: `string`\n\nPrivate RSA JWK \"dp\" (First Factor CRT Exponent) Parameter\n\n***\n\n### dq?\n\n• `optional` **dq?**: `string`\n\nPrivate RSA JWK \"dq\" (Second Factor CRT Exponent) Parameter\n\n***\n\n### e?\n\n• `optional` **e?**: `string`\n\nRSA JWK \"e\" (Exponent) Parameter\n\n***\n\n### ext?\n\n• `optional` **ext?**: `boolean`\n\nJWK \"ext\" (Extractable) Parameter\n\n***\n\n### k?\n\n• `optional` **k?**: `string`\n\nOct JWK \"k\" (Key Value) Parameter\n\n***\n\n### key\\_ops?\n\n• `optional` **key\\_ops?**: `string`[]\n\nJWK \"key_ops\" (Key Operations) Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\nJWK \"kid\" (Key ID) Parameter\n\n***\n\n### kty?\n\n• `optional` **kty?**: `string`\n\nJWK \"kty\" (Key Type) Parameter\n\n***\n\n### n?\n\n• `optional` **n?**: `string`\n\nRSA JWK \"n\" (Modulus) Parameter\n\n***\n\n### p?\n\n• `optional` **p?**: `string`\n\nPrivate RSA JWK \"p\" (First Prime Factor) Parameter\n\n***\n\n### priv?\n\n• `optional` **priv?**: `string`\n\nAKP JWK \"priv\" (Private key) Parameter\n\n***\n\n### pub?\n\n• `optional` **pub?**: `string`\n\nAKP JWK \"pub\" (Public Key) Parameter\n\n***\n\n### q?\n\n• `optional` **q?**: `string`\n\nPrivate RSA JWK \"q\" (Second Prime Factor) Parameter\n\n***\n\n### qi?\n\n• `optional` **qi?**: `string`\n\nPrivate RSA JWK \"qi\" (First CRT Coefficient) Parameter\n\n***\n\n### use?\n\n• `optional` **use?**: `string`\n\nJWK \"use\" (Public Key Use) Parameter\n\n***\n\n### x?\n\n• `optional` **x?**: `string`\n\n- EC JWK \"x\" (X Coordinate) Parameter\n- OKP JWK \"x\" (The public key) Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\nJWK \"x5c\" (X.509 Certificate Chain) Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\nJWK \"x5t\" (X.509 Certificate SHA-1 Thumbprint) Parameter\n\n***\n\n### x5t#S256?\n\n• `optional` **x5t#S256?**: `string`\n\nJWK \"x5t#S256\" (X.509 Certificate SHA-256 Thumbprint) Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\nJWK \"x5u\" (X.509 URL) Parameter\n\n***\n\n### y?\n\n• `optional` **y?**: `string`\n\nEC JWK \"y\" (Y Coordinate) Parameter\n"
  },
  {
    "path": "docs/types/interfaces/JWKParameters.md",
    "content": "# Interface: JWKParameters\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nGeneric JSON Web Key Parameters.\n\n## Properties\n\n### alg?\n\n• `optional` **alg?**: `string`\n\nJWK \"alg\" (Algorithm) Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210)\n\n***\n\n### ext?\n\n• `optional` **ext?**: `boolean`\n\nJWK \"ext\" (Extractable) Parameter\n\n***\n\n### key\\_ops?\n\n• `optional` **key\\_ops?**: `string`[]\n\nJWK \"key_ops\" (Key Operations) Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\nJWK \"kid\" (Key ID) Parameter\n\n***\n\n### kty?\n\n• `optional` **kty?**: `string`\n\nJWK \"kty\" (Key Type) Parameter\n\n***\n\n### use?\n\n• `optional` **use?**: `string`\n\nJWK \"use\" (Public Key Use) Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\nJWK \"x5c\" (X.509 Certificate Chain) Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\nJWK \"x5t\" (X.509 Certificate SHA-1 Thumbprint) Parameter\n\n***\n\n### x5t#S256?\n\n• `optional` **x5t#S256?**: `string`\n\nJWK \"x5t#S256\" (X.509 Certificate SHA-256 Thumbprint) Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\nJWK \"x5u\" (X.509 URL) Parameter\n"
  },
  {
    "path": "docs/types/interfaces/JWK_AKP_Private.md",
    "content": "# Interface: JWK\\_AKP\\_Private\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nConvenience interface for Private AKP JSON Web Keys\n\n## Properties\n\n### alg\n\n• **alg**: `string`\n\nJWK \"alg\" (Algorithm) Parameter\n\n***\n\n### priv\n\n• **priv**: `string`\n\nAKP JWK \"priv\" (The Private Key) Parameter\n\n***\n\n### pub\n\n• **pub**: `string`\n\nAKP JWK \"pub\" (The Public key) Parameter\n\n***\n\n### ext?\n\n• `optional` **ext?**: `boolean`\n\nJWK \"ext\" (Extractable) Parameter\n\n***\n\n### key\\_ops?\n\n• `optional` **key\\_ops?**: `string`[]\n\nJWK \"key_ops\" (Key Operations) Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\nJWK \"kid\" (Key ID) Parameter\n\n***\n\n### kty?\n\n• `optional` **kty?**: `string`\n\nJWK \"kty\" (Key Type) Parameter\n\n***\n\n### use?\n\n• `optional` **use?**: `string`\n\nJWK \"use\" (Public Key Use) Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\nJWK \"x5c\" (X.509 Certificate Chain) Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\nJWK \"x5t\" (X.509 Certificate SHA-1 Thumbprint) Parameter\n\n***\n\n### x5t#S256?\n\n• `optional` **x5t#S256?**: `string`\n\nJWK \"x5t#S256\" (X.509 Certificate SHA-256 Thumbprint) Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\nJWK \"x5u\" (X.509 URL) Parameter\n"
  },
  {
    "path": "docs/types/interfaces/JWK_AKP_Public.md",
    "content": "# Interface: JWK\\_AKP\\_Public\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nConvenience interface for Public AKP JSON Web Keys\n\n## Properties\n\n### alg\n\n• **alg**: `string`\n\nJWK \"alg\" (Algorithm) Parameter\n\n***\n\n### pub\n\n• **pub**: `string`\n\nAKP JWK \"pub\" (The Public key) Parameter\n\n***\n\n### ext?\n\n• `optional` **ext?**: `boolean`\n\nJWK \"ext\" (Extractable) Parameter\n\n***\n\n### key\\_ops?\n\n• `optional` **key\\_ops?**: `string`[]\n\nJWK \"key_ops\" (Key Operations) Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\nJWK \"kid\" (Key ID) Parameter\n\n***\n\n### kty?\n\n• `optional` **kty?**: `string`\n\nJWK \"kty\" (Key Type) Parameter\n\n***\n\n### use?\n\n• `optional` **use?**: `string`\n\nJWK \"use\" (Public Key Use) Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\nJWK \"x5c\" (X.509 Certificate Chain) Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\nJWK \"x5t\" (X.509 Certificate SHA-1 Thumbprint) Parameter\n\n***\n\n### x5t#S256?\n\n• `optional` **x5t#S256?**: `string`\n\nJWK \"x5t#S256\" (X.509 Certificate SHA-256 Thumbprint) Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\nJWK \"x5u\" (X.509 URL) Parameter\n"
  },
  {
    "path": "docs/types/interfaces/JWK_EC_Private.md",
    "content": "# Interface: JWK\\_EC\\_Private\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nConvenience interface for Private EC JSON Web Keys\n\n## Properties\n\n### crv\n\n• **crv**: `string`\n\nEC JWK \"crv\" (Curve) Parameter\n\n***\n\n### d\n\n• **d**: `string`\n\nEC JWK \"d\" (ECC Private Key) Parameter\n\n***\n\n### x\n\n• **x**: `string`\n\nEC JWK \"x\" (X Coordinate) Parameter\n\n***\n\n### y\n\n• **y**: `string`\n\nEC JWK \"y\" (Y Coordinate) Parameter\n\n***\n\n### alg?\n\n• `optional` **alg?**: `string`\n\nJWK \"alg\" (Algorithm) Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210)\n\n***\n\n### ext?\n\n• `optional` **ext?**: `boolean`\n\nJWK \"ext\" (Extractable) Parameter\n\n***\n\n### key\\_ops?\n\n• `optional` **key\\_ops?**: `string`[]\n\nJWK \"key_ops\" (Key Operations) Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\nJWK \"kid\" (Key ID) Parameter\n\n***\n\n### kty?\n\n• `optional` **kty?**: `string`\n\nJWK \"kty\" (Key Type) Parameter\n\n***\n\n### use?\n\n• `optional` **use?**: `string`\n\nJWK \"use\" (Public Key Use) Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\nJWK \"x5c\" (X.509 Certificate Chain) Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\nJWK \"x5t\" (X.509 Certificate SHA-1 Thumbprint) Parameter\n\n***\n\n### x5t#S256?\n\n• `optional` **x5t#S256?**: `string`\n\nJWK \"x5t#S256\" (X.509 Certificate SHA-256 Thumbprint) Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\nJWK \"x5u\" (X.509 URL) Parameter\n"
  },
  {
    "path": "docs/types/interfaces/JWK_EC_Public.md",
    "content": "# Interface: JWK\\_EC\\_Public\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nConvenience interface for Public EC JSON Web Keys\n\n## Properties\n\n### crv\n\n• **crv**: `string`\n\nEC JWK \"crv\" (Curve) Parameter\n\n***\n\n### x\n\n• **x**: `string`\n\nEC JWK \"x\" (X Coordinate) Parameter\n\n***\n\n### y\n\n• **y**: `string`\n\nEC JWK \"y\" (Y Coordinate) Parameter\n\n***\n\n### alg?\n\n• `optional` **alg?**: `string`\n\nJWK \"alg\" (Algorithm) Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210)\n\n***\n\n### ext?\n\n• `optional` **ext?**: `boolean`\n\nJWK \"ext\" (Extractable) Parameter\n\n***\n\n### key\\_ops?\n\n• `optional` **key\\_ops?**: `string`[]\n\nJWK \"key_ops\" (Key Operations) Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\nJWK \"kid\" (Key ID) Parameter\n\n***\n\n### kty?\n\n• `optional` **kty?**: `string`\n\nJWK \"kty\" (Key Type) Parameter\n\n***\n\n### use?\n\n• `optional` **use?**: `string`\n\nJWK \"use\" (Public Key Use) Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\nJWK \"x5c\" (X.509 Certificate Chain) Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\nJWK \"x5t\" (X.509 Certificate SHA-1 Thumbprint) Parameter\n\n***\n\n### x5t#S256?\n\n• `optional` **x5t#S256?**: `string`\n\nJWK \"x5t#S256\" (X.509 Certificate SHA-256 Thumbprint) Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\nJWK \"x5u\" (X.509 URL) Parameter\n"
  },
  {
    "path": "docs/types/interfaces/JWK_OKP_Private.md",
    "content": "# Interface: JWK\\_OKP\\_Private\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nConvenience interface for Private OKP JSON Web Keys\n\n## Properties\n\n### crv\n\n• **crv**: `string`\n\nOKP JWK \"crv\" (The Subtype of Key Pair) Parameter\n\n***\n\n### d\n\n• **d**: `string`\n\nOKP JWK \"d\" (The Private Key) Parameter\n\n***\n\n### x\n\n• **x**: `string`\n\nOKP JWK \"x\" (The public key) Parameter\n\n***\n\n### alg?\n\n• `optional` **alg?**: `string`\n\nJWK \"alg\" (Algorithm) Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210)\n\n***\n\n### ext?\n\n• `optional` **ext?**: `boolean`\n\nJWK \"ext\" (Extractable) Parameter\n\n***\n\n### key\\_ops?\n\n• `optional` **key\\_ops?**: `string`[]\n\nJWK \"key_ops\" (Key Operations) Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\nJWK \"kid\" (Key ID) Parameter\n\n***\n\n### kty?\n\n• `optional` **kty?**: `string`\n\nJWK \"kty\" (Key Type) Parameter\n\n***\n\n### use?\n\n• `optional` **use?**: `string`\n\nJWK \"use\" (Public Key Use) Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\nJWK \"x5c\" (X.509 Certificate Chain) Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\nJWK \"x5t\" (X.509 Certificate SHA-1 Thumbprint) Parameter\n\n***\n\n### x5t#S256?\n\n• `optional` **x5t#S256?**: `string`\n\nJWK \"x5t#S256\" (X.509 Certificate SHA-256 Thumbprint) Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\nJWK \"x5u\" (X.509 URL) Parameter\n"
  },
  {
    "path": "docs/types/interfaces/JWK_OKP_Public.md",
    "content": "# Interface: JWK\\_OKP\\_Public\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nConvenience interface for Public OKP JSON Web Keys\n\n## Properties\n\n### crv\n\n• **crv**: `string`\n\nOKP JWK \"crv\" (The Subtype of Key Pair) Parameter\n\n***\n\n### x\n\n• **x**: `string`\n\nOKP JWK \"x\" (The public key) Parameter\n\n***\n\n### alg?\n\n• `optional` **alg?**: `string`\n\nJWK \"alg\" (Algorithm) Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210)\n\n***\n\n### ext?\n\n• `optional` **ext?**: `boolean`\n\nJWK \"ext\" (Extractable) Parameter\n\n***\n\n### key\\_ops?\n\n• `optional` **key\\_ops?**: `string`[]\n\nJWK \"key_ops\" (Key Operations) Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\nJWK \"kid\" (Key ID) Parameter\n\n***\n\n### kty?\n\n• `optional` **kty?**: `string`\n\nJWK \"kty\" (Key Type) Parameter\n\n***\n\n### use?\n\n• `optional` **use?**: `string`\n\nJWK \"use\" (Public Key Use) Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\nJWK \"x5c\" (X.509 Certificate Chain) Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\nJWK \"x5t\" (X.509 Certificate SHA-1 Thumbprint) Parameter\n\n***\n\n### x5t#S256?\n\n• `optional` **x5t#S256?**: `string`\n\nJWK \"x5t#S256\" (X.509 Certificate SHA-256 Thumbprint) Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\nJWK \"x5u\" (X.509 URL) Parameter\n"
  },
  {
    "path": "docs/types/interfaces/JWK_RSA_Private.md",
    "content": "# Interface: JWK\\_RSA\\_Private\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nConvenience interface for Private RSA JSON Web Keys\n\n## Properties\n\n### d\n\n• **d**: `string`\n\nRSA JWK \"d\" (Private Exponent) Parameter\n\n***\n\n### dp\n\n• **dp**: `string`\n\nRSA JWK \"dp\" (First Factor CRT Exponent) Parameter\n\n***\n\n### dq\n\n• **dq**: `string`\n\nRSA JWK \"dq\" (Second Factor CRT Exponent) Parameter\n\n***\n\n### e\n\n• **e**: `string`\n\nRSA JWK \"e\" (Exponent) Parameter\n\n***\n\n### n\n\n• **n**: `string`\n\nRSA JWK \"n\" (Modulus) Parameter\n\n***\n\n### p\n\n• **p**: `string`\n\nRSA JWK \"p\" (First Prime Factor) Parameter\n\n***\n\n### q\n\n• **q**: `string`\n\nRSA JWK \"q\" (Second Prime Factor) Parameter\n\n***\n\n### qi\n\n• **qi**: `string`\n\nRSA JWK \"qi\" (First CRT Coefficient) Parameter\n\n***\n\n### alg?\n\n• `optional` **alg?**: `string`\n\nJWK \"alg\" (Algorithm) Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210)\n\n***\n\n### ext?\n\n• `optional` **ext?**: `boolean`\n\nJWK \"ext\" (Extractable) Parameter\n\n***\n\n### key\\_ops?\n\n• `optional` **key\\_ops?**: `string`[]\n\nJWK \"key_ops\" (Key Operations) Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\nJWK \"kid\" (Key ID) Parameter\n\n***\n\n### kty?\n\n• `optional` **kty?**: `string`\n\nJWK \"kty\" (Key Type) Parameter\n\n***\n\n### use?\n\n• `optional` **use?**: `string`\n\nJWK \"use\" (Public Key Use) Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\nJWK \"x5c\" (X.509 Certificate Chain) Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\nJWK \"x5t\" (X.509 Certificate SHA-1 Thumbprint) Parameter\n\n***\n\n### x5t#S256?\n\n• `optional` **x5t#S256?**: `string`\n\nJWK \"x5t#S256\" (X.509 Certificate SHA-256 Thumbprint) Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\nJWK \"x5u\" (X.509 URL) Parameter\n"
  },
  {
    "path": "docs/types/interfaces/JWK_RSA_Public.md",
    "content": "# Interface: JWK\\_RSA\\_Public\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nConvenience interface for Public RSA JSON Web Keys\n\n## Properties\n\n### e\n\n• **e**: `string`\n\nRSA JWK \"e\" (Exponent) Parameter\n\n***\n\n### n\n\n• **n**: `string`\n\nRSA JWK \"n\" (Modulus) Parameter\n\n***\n\n### alg?\n\n• `optional` **alg?**: `string`\n\nJWK \"alg\" (Algorithm) Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210)\n\n***\n\n### ext?\n\n• `optional` **ext?**: `boolean`\n\nJWK \"ext\" (Extractable) Parameter\n\n***\n\n### key\\_ops?\n\n• `optional` **key\\_ops?**: `string`[]\n\nJWK \"key_ops\" (Key Operations) Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\nJWK \"kid\" (Key ID) Parameter\n\n***\n\n### kty?\n\n• `optional` **kty?**: `string`\n\nJWK \"kty\" (Key Type) Parameter\n\n***\n\n### use?\n\n• `optional` **use?**: `string`\n\nJWK \"use\" (Public Key Use) Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\nJWK \"x5c\" (X.509 Certificate Chain) Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\nJWK \"x5t\" (X.509 Certificate SHA-1 Thumbprint) Parameter\n\n***\n\n### x5t#S256?\n\n• `optional` **x5t#S256?**: `string`\n\nJWK \"x5t#S256\" (X.509 Certificate SHA-256 Thumbprint) Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\nJWK \"x5u\" (X.509 URL) Parameter\n"
  },
  {
    "path": "docs/types/interfaces/JWK_oct.md",
    "content": "# Interface: JWK\\_oct\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nConvenience interface for oct JSON Web Keys\n\n## Properties\n\n### k\n\n• **k**: `string`\n\nOct JWK \"k\" (Key Value) Parameter\n\n***\n\n### alg?\n\n• `optional` **alg?**: `string`\n\nJWK \"alg\" (Algorithm) Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210)\n\n***\n\n### ext?\n\n• `optional` **ext?**: `boolean`\n\nJWK \"ext\" (Extractable) Parameter\n\n***\n\n### key\\_ops?\n\n• `optional` **key\\_ops?**: `string`[]\n\nJWK \"key_ops\" (Key Operations) Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\nJWK \"kid\" (Key ID) Parameter\n\n***\n\n### kty?\n\n• `optional` **kty?**: `string`\n\nJWK \"kty\" (Key Type) Parameter\n\n***\n\n### use?\n\n• `optional` **use?**: `string`\n\nJWK \"use\" (Public Key Use) Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\nJWK \"x5c\" (X.509 Certificate Chain) Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\nJWK \"x5t\" (X.509 Certificate SHA-1 Thumbprint) Parameter\n\n***\n\n### x5t#S256?\n\n• `optional` **x5t#S256?**: `string`\n\nJWK \"x5t#S256\" (X.509 Certificate SHA-256 Thumbprint) Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\nJWK \"x5u\" (X.509 URL) Parameter\n"
  },
  {
    "path": "docs/types/interfaces/JWSHeaderParameters.md",
    "content": "# Interface: JWSHeaderParameters\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nRecognized JWS Header Parameters, any other Header Members may also be present.\n\n## Indexable\n\n> \\[`propName`: `string`\\]: `unknown`\n\nAny other JWS Header member.\n\n## Properties\n\n### alg?\n\n• `optional` **alg?**: `string`\n\nJWS \"alg\" (Algorithm) Header Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg)\n\n***\n\n### b64?\n\n• `optional` **b64?**: `boolean`\n\nThis JWS Extension Header Parameter modifies the JWS Payload representation and the JWS Signing\nInput computation as per [RFC7797](https://www.rfc-editor.org/rfc/rfc7797).\n\n***\n\n### crit?\n\n• `optional` **crit?**: `string`[]\n\nJWS \"crit\" (Critical) Header Parameter\n\n***\n\n### cty?\n\n• `optional` **cty?**: `string`\n\n\"cty\" (Content Type) Header Parameter\n\n***\n\n### jku?\n\n• `optional` **jku?**: `string`\n\n\"jku\" (JWK Set URL) Header Parameter\n\n***\n\n### jwk?\n\n• `optional` **jwk?**: [`Pick`](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys)\\<[`JWK`](JWK.md), `\"x\"` \\| `\"y\"` \\| `\"crv\"` \\| `\"e\"` \\| `\"n\"` \\| `\"pub\"` \\| `\"kty\"` \\| `\"alg\"`\\>\n\n\"jwk\" (JSON Web Key) Header Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\n\"kid\" (Key ID) Header Parameter\n\n***\n\n### typ?\n\n• `optional` **typ?**: `string`\n\n\"typ\" (Type) Header Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\n\"x5c\" (X.509 Certificate Chain) Header Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\n\"x5t\" (X.509 Certificate SHA-1 Thumbprint) Header Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\n\"x5u\" (X.509 URL) Header Parameter\n"
  },
  {
    "path": "docs/types/interfaces/JWTClaimVerificationOptions.md",
    "content": "# Interface: JWTClaimVerificationOptions\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nJWT Claims Set verification options.\n\n## Properties\n\n### audience?\n\n• `optional` **audience?**: `string` \\| `string`[]\n\nExpected JWT \"aud\" (Audience) Claim value(s).\n\nThis option makes the JWT \"aud\" (Audience) Claim presence required.\n\n***\n\n### clockTolerance?\n\n• `optional` **clockTolerance?**: `string` \\| `number`\n\nClock skew tolerance\n\n- In seconds when number (e.g. 5)\n- Resolved into a number of seconds when a string (e.g. \"5 seconds\", \"10 minutes\", \"2 hours\").\n\nUsed when validating the JWT \"nbf\" (Not Before) and \"exp\" (Expiration Time) claims, and when\nvalidating the \"iat\" (Issued At) claim if the [`maxTokenAge` option](#maxtokenage) is set.\n\n***\n\n### currentDate?\n\n• `optional` **currentDate?**: [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date)\n\nDate to use when comparing NumericDate claims, defaults to `new Date()`.\n\n***\n\n### issuer?\n\n• `optional` **issuer?**: `string` \\| `string`[]\n\nExpected JWT \"iss\" (Issuer) Claim value(s).\n\nThis option makes the JWT \"iss\" (Issuer) Claim presence required.\n\n***\n\n### maxTokenAge?\n\n• `optional` **maxTokenAge?**: `string` \\| `number`\n\nMaximum time elapsed (in seconds) from the JWT \"iat\" (Issued At) Claim value.\n\n- In seconds when number (e.g. 5)\n- Resolved into a number of seconds when a string (e.g. \"5 seconds\", \"10 minutes\", \"2 hours\").\n\nThis option makes the JWT \"iat\" (Issued At) Claim presence required.\n\n***\n\n### requiredClaims?\n\n• `optional` **requiredClaims?**: `string`[]\n\nArray of required Claim Names that must be present in the JWT Claims Set. Default is that: if\nthe [`issuer` option](#issuer) is set, then JWT \"iss\" (Issuer) Claim must be present; if the\n[`audience` option](#audience) is set, then JWT \"aud\" (Audience) Claim must be present; if\nthe [`subject` option](#subject) is set, then JWT \"sub\" (Subject) Claim must be present; if\nthe [`maxTokenAge` option](#maxtokenage) is set, then JWT \"iat\" (Issued At) Claim must be\npresent.\n\n***\n\n### subject?\n\n• `optional` **subject?**: `string`\n\nExpected JWT \"sub\" (Subject) Claim value.\n\nThis option makes the JWT \"sub\" (Subject) Claim presence required.\n\n***\n\n### typ?\n\n• `optional` **typ?**: `string`\n\nExpected JWT \"typ\" (Type) Header Parameter value.\n\nThis option makes the JWT \"typ\" (Type) Header Parameter presence required.\n"
  },
  {
    "path": "docs/types/interfaces/JWTDecryptResult.md",
    "content": "# Interface: JWTDecryptResult\\<PayloadType\\>\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nEncrypted JSON Web Token (JWT) decryption result\n\n## Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `PayloadType` | [`JWTPayload`](JWTPayload.md) |\n\n## Properties\n\n### payload\n\n• **payload**: `PayloadType` & [`JWTPayload`](JWTPayload.md)\n\nJWT Claims Set.\n\n***\n\n### protectedHeader\n\n• **protectedHeader**: [`CompactJWEHeaderParameters`](CompactJWEHeaderParameters.md)\n\nJWE Protected Header.\n"
  },
  {
    "path": "docs/types/interfaces/JWTHeaderParameters.md",
    "content": "# Interface: JWTHeaderParameters\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nRecognized Signed JWT Header Parameters, any other Header Members may also be present.\n\n## Indexable\n\n> \\[`propName`: `string`\\]: `unknown`\n\nAny other JWS Header member.\n\n## Properties\n\n### alg\n\n• **alg**: `string`\n\nJWS \"alg\" (Algorithm) Header Parameter\n\n#### See\n\n[Algorithm Key Requirements](https://github.com/panva/jose/issues/210#jws-alg)\n\n***\n\n### b64?\n\n• `optional` **b64?**: `true`\n\nThis JWS Extension Header Parameter modifies the JWS Payload representation and the JWS Signing\nInput computation as per [RFC7797](https://www.rfc-editor.org/rfc/rfc7797).\n\n***\n\n### crit?\n\n• `optional` **crit?**: `string`[]\n\nJWS \"crit\" (Critical) Header Parameter\n\n***\n\n### cty?\n\n• `optional` **cty?**: `string`\n\n\"cty\" (Content Type) Header Parameter\n\n***\n\n### jku?\n\n• `optional` **jku?**: `string`\n\n\"jku\" (JWK Set URL) Header Parameter\n\n***\n\n### jwk?\n\n• `optional` **jwk?**: [`Pick`](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys)\\<[`JWK`](JWK.md), `\"x\"` \\| `\"y\"` \\| `\"crv\"` \\| `\"e\"` \\| `\"n\"` \\| `\"pub\"` \\| `\"kty\"` \\| `\"alg\"`\\>\n\n\"jwk\" (JSON Web Key) Header Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\n\"kid\" (Key ID) Header Parameter\n\n***\n\n### typ?\n\n• `optional` **typ?**: `string`\n\n\"typ\" (Type) Header Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\n\"x5c\" (X.509 Certificate Chain) Header Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\n\"x5t\" (X.509 Certificate SHA-1 Thumbprint) Header Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\n\"x5u\" (X.509 URL) Header Parameter\n"
  },
  {
    "path": "docs/types/interfaces/JWTPayload.md",
    "content": "# Interface: JWTPayload\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nRecognized JWT Claims Set members, any other members may also be present.\n\n## Indexable\n\n> \\[`propName`: `string`\\]: `unknown`\n\nAny other JWT Claim Set member.\n\n## Properties\n\n### aud?\n\n• `optional` **aud?**: `string` \\| `string`[]\n\nJWT Audience\n\n#### See\n\n[RFC7519#section-4.1.3](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.3)\n\n***\n\n### exp?\n\n• `optional` **exp?**: `number`\n\nJWT Expiration Time\n\n#### See\n\n[RFC7519#section-4.1.4](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.4)\n\n***\n\n### iat?\n\n• `optional` **iat?**: `number`\n\nJWT Issued At\n\n#### See\n\n[RFC7519#section-4.1.6](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6)\n\n***\n\n### iss?\n\n• `optional` **iss?**: `string`\n\nJWT Issuer\n\n#### See\n\n[RFC7519#section-4.1.1](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.1)\n\n***\n\n### jti?\n\n• `optional` **jti?**: `string`\n\nJWT ID\n\n#### See\n\n[RFC7519#section-4.1.7](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.7)\n\n***\n\n### nbf?\n\n• `optional` **nbf?**: `number`\n\nJWT Not Before\n\n#### See\n\n[RFC7519#section-4.1.5](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.5)\n\n***\n\n### sub?\n\n• `optional` **sub?**: `string`\n\nJWT Subject\n\n#### See\n\n[RFC7519#section-4.1.2](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.2)\n"
  },
  {
    "path": "docs/types/interfaces/JWTVerifyResult.md",
    "content": "# Interface: JWTVerifyResult\\<PayloadType\\>\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nSigned JSON Web Token (JWT) verification result\n\n## Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `PayloadType` | [`JWTPayload`](JWTPayload.md) |\n\n## Properties\n\n### payload\n\n• **payload**: `PayloadType` & [`JWTPayload`](JWTPayload.md)\n\nJWT Claims Set.\n\n***\n\n### protectedHeader\n\n• **protectedHeader**: [`JWTHeaderParameters`](JWTHeaderParameters.md)\n\nJWS Protected Header.\n"
  },
  {
    "path": "docs/types/interfaces/JoseHeaderParameters.md",
    "content": "# Interface: JoseHeaderParameters\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nHeader Parameters common to JWE and JWS\n\n## Properties\n\n### cty?\n\n• `optional` **cty?**: `string`\n\n\"cty\" (Content Type) Header Parameter\n\n***\n\n### jku?\n\n• `optional` **jku?**: `string`\n\n\"jku\" (JWK Set URL) Header Parameter\n\n***\n\n### jwk?\n\n• `optional` **jwk?**: [`Pick`](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys)\\<[`JWK`](JWK.md), `\"x\"` \\| `\"y\"` \\| `\"crv\"` \\| `\"e\"` \\| `\"n\"` \\| `\"pub\"` \\| `\"kty\"` \\| `\"alg\"`\\>\n\n\"jwk\" (JSON Web Key) Header Parameter\n\n***\n\n### kid?\n\n• `optional` **kid?**: `string`\n\n\"kid\" (Key ID) Header Parameter\n\n***\n\n### typ?\n\n• `optional` **typ?**: `string`\n\n\"typ\" (Type) Header Parameter\n\n***\n\n### x5c?\n\n• `optional` **x5c?**: `string`[]\n\n\"x5c\" (X.509 Certificate Chain) Header Parameter\n\n***\n\n### x5t?\n\n• `optional` **x5t?**: `string`\n\n\"x5t\" (X.509 Certificate SHA-1 Thumbprint) Header Parameter\n\n***\n\n### x5u?\n\n• `optional` **x5u?**: `string`\n\n\"x5u\" (X.509 URL) Header Parameter\n"
  },
  {
    "path": "docs/types/interfaces/KeyObject.md",
    "content": "# Interface: KeyObject\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n[KeyObject](https://nodejs.org/api/crypto.html#class-keyobject) is a representation of a key/secret available in the Node.js runtime. You may\nuse the Node.js runtime APIs [createPublicKey](https://nodejs.org/api/crypto.html#cryptocreatepublickeykey), [createPrivateKey](https://nodejs.org/api/crypto.html#cryptocreateprivatekeykey), and\n[createSecretKey](https://nodejs.org/api/crypto.html#cryptocreatesecretkeykey-encoding) to obtain a [KeyObject](https://nodejs.org/api/crypto.html#class-keyobject) from your existing key material.\n\n## Properties\n\n### type\n\n• **type**: `string`\n"
  },
  {
    "path": "docs/types/interfaces/ProduceJWT.md",
    "content": "# Interface: ProduceJWT\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nGeneric interface for JWT producing classes.\n\n## Methods\n\n### setAudience()\n\n▸ **setAudience**(`audience`): `this`\n\nSet the \"aud\" (Audience) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `audience` | `string` \\| `string`[] | \"aud\" (Audience) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setExpirationTime()\n\n▸ **setExpirationTime**(`input`): `this`\n\nSet the \"exp\" (Expiration Time) Claim.\n\n- If a `number` is passed as an argument it is used as the claim directly.\n- If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n  claim.\n- If a `string` is passed as an argument it is resolved to a time span, and then added to the\n  current unix timestamp and used as the claim.\n\nFormat used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\nday\".\n\nValid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n\"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n\"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\nalias for a year.\n\nIf the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\nsubtracted from the current unix timestamp. A \"from now\" suffix can also be used for\nreadability when adding to the current unix timestamp.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `input` | `string` \\| `number` \\| [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | \"exp\" (Expiration Time) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setIssuedAt()\n\n▸ **setIssuedAt**(`input?`): `this`\n\nSet the \"iat\" (Issued At) Claim.\n\n- If no argument is used the current unix timestamp is used as the claim.\n- If a `number` is passed as an argument it is used as the claim directly.\n- If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n  claim.\n- If a `string` is passed as an argument it is resolved to a time span, and then added to the\n  current unix timestamp and used as the claim.\n\nFormat used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\nday\".\n\nValid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n\"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n\"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\nalias for a year.\n\nIf the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\nsubtracted from the current unix timestamp. A \"from now\" suffix can also be used for\nreadability when adding to the current unix timestamp.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `input?` | `string` \\| `number` \\| [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | \"iat\" (Expiration Time) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setIssuer()\n\n▸ **setIssuer**(`issuer`): `this`\n\nSet the \"iss\" (Issuer) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `issuer` | `string` | \"Issuer\" Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setJti()\n\n▸ **setJti**(`jwtId`): `this`\n\nSet the \"jti\" (JWT ID) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwtId` | `string` | \"jti\" (JWT ID) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setNotBefore()\n\n▸ **setNotBefore**(`input`): `this`\n\nSet the \"nbf\" (Not Before) Claim.\n\n- If a `number` is passed as an argument it is used as the claim directly.\n- If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n  claim.\n- If a `string` is passed as an argument it is resolved to a time span, and then added to the\n  current unix timestamp and used as the claim.\n\nFormat used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\nday\".\n\nValid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n\"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n\"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\nalias for a year.\n\nIf the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\nsubtracted from the current unix timestamp. A \"from now\" suffix can also be used for\nreadability when adding to the current unix timestamp.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `input` | `string` \\| `number` \\| [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | \"nbf\" (Not Before) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n\n***\n\n### setSubject()\n\n▸ **setSubject**(`subject`): `this`\n\nSet the \"sub\" (Subject) Claim.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `subject` | `string` | \"sub\" (Subject) Claim value to set on the JWT Claims Set. |\n\n#### Returns\n\n`this`\n"
  },
  {
    "path": "docs/types/interfaces/ResolvedKey.md",
    "content": "# Interface: ResolvedKey\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nWhen key resolver functions are used this becomes part of successful resolves\n\n## Properties\n\n### key\n\n• **key**: [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) \\| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey)\n\nKey resolved from the key resolver function.\n"
  },
  {
    "path": "docs/types/interfaces/SignOptions.md",
    "content": "# Interface: SignOptions\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nJWS Signing options.\n\n## Properties\n\n### crit?\n\n• `optional` **crit?**: `object`\n\nAn object with keys representing recognized \"crit\" (Critical) Header Parameter names. The value\nfor those is either `true` or `false`. `true` when the Header Parameter MUST be integrity\nprotected, `false` when it's irrelevant.\n\nThis makes the \"Extension Header Parameter \"...\" is not recognized\" error go away.\n\nUse this when a given JWS/JWT/JWE profile requires the use of proprietary non-registered \"crit\"\n(Critical) Header Parameters. This will only make sure the Header Parameter is syntactically\ncorrect when provided and that it is optionally integrity protected. It will not process the\nHeader Parameter in any way or reject the operation if it is missing. You MUST still verify the\nHeader Parameter was present and process it according to the profile's validation steps after\nthe operation succeeds.\n\nThe JWS extension Header Parameter `b64` is always recognized and processed properly. No other\nregistered Header Parameters that need this kind of default built-in treatment are currently\navailable.\n\n#### Index Signature\n\n\\[`propName`: `string`\\]: `boolean`\n"
  },
  {
    "path": "docs/types/interfaces/VerifyOptions.md",
    "content": "# Interface: VerifyOptions\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nJWS Verification options.\n\n## Properties\n\n### algorithms?\n\n• `optional` **algorithms?**: `string`[]\n\nA list of accepted JWS \"alg\" (Algorithm) Header Parameter values. By default all \"alg\"\n(Algorithm) values applicable for the used key/secret are allowed.\n\n> [!NOTE]\\\n> Unsecured JWTs (`{ \"alg\": \"none\" }`) are never accepted by this API.\n\n***\n\n### crit?\n\n• `optional` **crit?**: `object`\n\nAn object with keys representing recognized \"crit\" (Critical) Header Parameter names. The value\nfor those is either `true` or `false`. `true` when the Header Parameter MUST be integrity\nprotected, `false` when it's irrelevant.\n\nThis makes the \"Extension Header Parameter \"...\" is not recognized\" error go away.\n\nUse this when a given JWS/JWT/JWE profile requires the use of proprietary non-registered \"crit\"\n(Critical) Header Parameters. This will only make sure the Header Parameter is syntactically\ncorrect when provided and that it is optionally integrity protected. It will not process the\nHeader Parameter in any way or reject the operation if it is missing. You MUST still verify the\nHeader Parameter was present and process it according to the profile's validation steps after\nthe operation succeeds.\n\nThe JWS extension Header Parameter `b64` is always recognized and processed properly. No other\nregistered Header Parameters that need this kind of default built-in treatment are currently\navailable.\n\n#### Index Signature\n\n\\[`propName`: `string`\\]: `boolean`\n"
  },
  {
    "path": "docs/types/type-aliases/CryptoKey.md",
    "content": "# Type Alias: CryptoKey\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n• **CryptoKey** = [`Extract`](https://www.typescriptlang.org/docs/handbook/utility-types.html#extracttype-union)\\<[`Awaited`](https://www.typescriptlang.org/docs/handbook/utility-types.html#awaitedtype)\\<[`ReturnType`](https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype)\\<*typeof* [`crypto.subtle.generateKey`](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/generateKey)\\>\\>, \\{ `type`: `string`; \\}\\>\n\n[CryptoKey](https://developer.mozilla.org/docs/Web/API/CryptoKey) is a representation of a key/secret available in all supported runtimes. In\naddition to the [Key Import Functions](../../key/import/README.md) you may use the\n[SubtleCrypto.importKey](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/importKey) API to obtain a [CryptoKey](https://developer.mozilla.org/docs/Web/API/CryptoKey) from your existing key\nmaterial.\n"
  },
  {
    "path": "docs/util/base64url/README.md",
    "content": "# util/base64url\n\nBase64URL encoding and decoding utilities\n\n## Functions\n\n- [decode](functions/decode.md)\n- [encode](functions/encode.md)\n"
  },
  {
    "path": "docs/util/base64url/functions/decode.md",
    "content": "# Function: decode()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **decode**(`input`): [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n\nDecodes a Base64URL encoded input.\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `input` | `string` \\| [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) |\n\n## Returns\n\n[`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)\n"
  },
  {
    "path": "docs/util/base64url/functions/encode.md",
    "content": "# Function: encode()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **encode**(`input`): `string`\n\nEncodes an input using Base64URL with no padding.\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `input` | `string` \\| [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) |\n\n## Returns\n\n`string`\n"
  },
  {
    "path": "docs/util/decode_jwt/README.md",
    "content": "# util/decode\\_jwt\n\nJSON Web Token (JWT) Claims Set Decoding (no validation, no signature checking)\n\n## Functions\n\n- [decodeJwt](functions/decodeJwt.md)\n"
  },
  {
    "path": "docs/util/decode_jwt/functions/decodeJwt.md",
    "content": "# Function: decodeJwt()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **decodeJwt**\\<`PayloadType`\\>(`jwt`): `PayloadType` & [`JWTPayload`](../../../types/interfaces/JWTPayload.md)\n\nDecodes a signed JSON Web Token payload. This does not validate the JWT Claims Set types or\nvalues. This does not validate the JWS Signature. For a proper Signed JWT Claims Set validation\nand JWS signature verification use `jose.jwtVerify()`. For an encrypted JWT Claims Set validation\nand JWE decryption use `jose.jwtDecrypt()`.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/jwt/decode'`.\n\n## Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `PayloadType` | [`JWTPayload`](../../../types/interfaces/JWTPayload.md) |\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `jwt` | `string` | JWT token in compact JWS serialization. |\n\n## Returns\n\n`PayloadType` & [`JWTPayload`](../../../types/interfaces/JWTPayload.md)\n\n## Example\n\n```js\nconst claims = jose.decodeJwt(token)\nconsole.log(claims)\n```\n"
  },
  {
    "path": "docs/util/decode_protected_header/README.md",
    "content": "# util/decode\\_protected\\_header\n\nJOSE Protected Header Decoding (JWE, JWS, all serialization syntaxes)\n\n## Type Aliases\n\n- [ProtectedHeaderParameters](type-aliases/ProtectedHeaderParameters.md)\n\n## Functions\n\n- [decodeProtectedHeader](functions/decodeProtectedHeader.md)\n"
  },
  {
    "path": "docs/util/decode_protected_header/functions/decodeProtectedHeader.md",
    "content": "# Function: decodeProtectedHeader()\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n▸ **decodeProtectedHeader**(`token`): [`ProtectedHeaderParameters`](../type-aliases/ProtectedHeaderParameters.md)\n\nDecodes the Protected Header of a JWE/JWS/JWT token utilizing any JOSE serialization.\n\nThis function is exported (as a named export) from the main `'jose'` module entry point as well\nas from its subpath export `'jose/decode/protected_header'`.\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `token` | `string` \\| `object` | JWE/JWS/JWT token in any JOSE serialization. |\n\n## Returns\n\n[`ProtectedHeaderParameters`](../type-aliases/ProtectedHeaderParameters.md)\n\n## Example\n\n```js\nconst protectedHeader = jose.decodeProtectedHeader(token)\nconsole.log(protectedHeader)\n```\n"
  },
  {
    "path": "docs/util/decode_protected_header/type-aliases/ProtectedHeaderParameters.md",
    "content": "# Type Alias: ProtectedHeaderParameters\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\n• **ProtectedHeaderParameters** = [`JWSHeaderParameters`](../../../types/interfaces/JWSHeaderParameters.md) & [`JWEHeaderParameters`](../../../types/interfaces/JWEHeaderParameters.md)\n\nJWE and JWS Header Parameters\n"
  },
  {
    "path": "docs/util/errors/README.md",
    "content": "# util/errors\n\nJOSE module errors and error codes\n\n## Classes\n\n- [JOSEAlgNotAllowed](classes/JOSEAlgNotAllowed.md)\n- [JOSEError](classes/JOSEError.md)\n- [JOSENotSupported](classes/JOSENotSupported.md)\n- [JWEDecryptionFailed](classes/JWEDecryptionFailed.md)\n- [JWEInvalid](classes/JWEInvalid.md)\n- [JWKInvalid](classes/JWKInvalid.md)\n- [JWKSInvalid](classes/JWKSInvalid.md)\n- [JWKSMultipleMatchingKeys](classes/JWKSMultipleMatchingKeys.md)\n- [JWKSNoMatchingKey](classes/JWKSNoMatchingKey.md)\n- [JWKSTimeout](classes/JWKSTimeout.md)\n- [JWSInvalid](classes/JWSInvalid.md)\n- [JWSSignatureVerificationFailed](classes/JWSSignatureVerificationFailed.md)\n- [JWTClaimValidationFailed](classes/JWTClaimValidationFailed.md)\n- [JWTExpired](classes/JWTExpired.md)\n- [JWTInvalid](classes/JWTInvalid.md)\n"
  },
  {
    "path": "docs/util/errors/classes/JOSEAlgNotAllowed.md",
    "content": "# Class: JOSEAlgNotAllowed\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAn error subclass thrown when a JOSE Algorithm is not allowed per developer preference.\n\n## Examples\n\nChecking thrown error is this one using a stable error code\n\n```js\nif (err.code === 'ERR_JOSE_ALG_NOT_ALLOWED') {\n  // ...\n}\n```\n\nChecking thrown error is this one using `instanceof`\n\n```js\nif (err instanceof jose.errors.JOSEAlgNotAllowed) {\n  // ...\n}\n```\n\n## Properties\n\n### code\n\n• **code**: `string` = `'ERR_JOSE_ALG_NOT_ALLOWED'`\n\nA unique error code for JOSEAlgNotAllowed.\n"
  },
  {
    "path": "docs/util/errors/classes/JOSEError.md",
    "content": "# Class: JOSEError\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nA generic Error that all other JOSE specific Error subclasses extend.\n\n## Example\n\nChecking thrown error is a JOSE one\n\n```js\nif (err instanceof jose.errors.JOSEError) {\n  // ...\n}\n```\n\n## Properties\n\n### code\n\n• **code**: `string` = `'ERR_JOSE_GENERIC'`\n\nA unique error code for JOSEError.\n"
  },
  {
    "path": "docs/util/errors/classes/JOSENotSupported.md",
    "content": "# Class: JOSENotSupported\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAn error subclass thrown when a particular feature or algorithm is not supported by this\nimplementation or JOSE in general.\n\n## Examples\n\nChecking thrown error is this one using a stable error code\n\n```js\nif (err.code === 'ERR_JOSE_NOT_SUPPORTED') {\n  // ...\n}\n```\n\nChecking thrown error is this one using `instanceof`\n\n```js\nif (err instanceof jose.errors.JOSENotSupported) {\n  // ...\n}\n```\n\n## Properties\n\n### code\n\n• **code**: `string` = `'ERR_JOSE_NOT_SUPPORTED'`\n\nA unique error code for JOSENotSupported.\n"
  },
  {
    "path": "docs/util/errors/classes/JWEDecryptionFailed.md",
    "content": "# Class: JWEDecryptionFailed\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAn error subclass thrown when a JWE ciphertext decryption fails.\n\n## Examples\n\nChecking thrown error is this one using a stable error code\n\n```js\nif (err.code === 'ERR_JWE_DECRYPTION_FAILED') {\n  // ...\n}\n```\n\nChecking thrown error is this one using `instanceof`\n\n```js\nif (err instanceof jose.errors.JWEDecryptionFailed) {\n  // ...\n}\n```\n\n## Properties\n\n### code\n\n• **code**: `string` = `'ERR_JWE_DECRYPTION_FAILED'`\n\nA unique error code for JWEDecryptionFailed.\n"
  },
  {
    "path": "docs/util/errors/classes/JWEInvalid.md",
    "content": "# Class: JWEInvalid\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAn error subclass thrown when a JWE is invalid.\n\n## Examples\n\nChecking thrown error is this one using a stable error code\n\n```js\nif (err.code === 'ERR_JWE_INVALID') {\n  // ...\n}\n```\n\nChecking thrown error is this one using `instanceof`\n\n```js\nif (err instanceof jose.errors.JWEInvalid) {\n  // ...\n}\n```\n\n## Properties\n\n### code\n\n• **code**: `string` = `'ERR_JWE_INVALID'`\n\nA unique error code for JWEInvalid.\n"
  },
  {
    "path": "docs/util/errors/classes/JWKInvalid.md",
    "content": "# Class: JWKInvalid\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAn error subclass thrown when a JWK is invalid.\n\n## Examples\n\nChecking thrown error is this one using a stable error code\n\n```js\nif (err.code === 'ERR_JWK_INVALID') {\n  // ...\n}\n```\n\nChecking thrown error is this one using `instanceof`\n\n```js\nif (err instanceof jose.errors.JWKInvalid) {\n  // ...\n}\n```\n\n## Properties\n\n### code\n\n• **code**: `string` = `'ERR_JWK_INVALID'`\n\nA unique error code for JWKInvalid.\n"
  },
  {
    "path": "docs/util/errors/classes/JWKSInvalid.md",
    "content": "# Class: JWKSInvalid\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAn error subclass thrown when a JWKS is invalid.\n\n## Examples\n\nChecking thrown error is this one using a stable error code\n\n```js\nif (err.code === 'ERR_JWKS_INVALID') {\n  // ...\n}\n```\n\nChecking thrown error is this one using `instanceof`\n\n```js\nif (err instanceof jose.errors.JWKSInvalid) {\n  // ...\n}\n```\n\n## Properties\n\n### code\n\n• **code**: `string` = `'ERR_JWKS_INVALID'`\n\nA unique error code for JWKSInvalid.\n"
  },
  {
    "path": "docs/util/errors/classes/JWKSMultipleMatchingKeys.md",
    "content": "# Class: JWKSMultipleMatchingKeys\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAn error subclass thrown when multiple keys match from a JWKS.\n\n## Examples\n\nChecking thrown error is this one using a stable error code\n\n```js\nif (err.code === 'ERR_JWKS_MULTIPLE_MATCHING_KEYS') {\n  // ...\n}\n```\n\nChecking thrown error is this one using `instanceof`\n\n```js\nif (err instanceof jose.errors.JWKSMultipleMatchingKeys) {\n  // ...\n}\n```\n\n## Properties\n\n### code\n\n• **code**: `string` = `'ERR_JWKS_MULTIPLE_MATCHING_KEYS'`\n\nA unique error code for JWKSMultipleMatchingKeys.\n"
  },
  {
    "path": "docs/util/errors/classes/JWKSNoMatchingKey.md",
    "content": "# Class: JWKSNoMatchingKey\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAn error subclass thrown when no keys match from a JWKS.\n\n## Examples\n\nChecking thrown error is this one using a stable error code\n\n```js\nif (err.code === 'ERR_JWKS_NO_MATCHING_KEY') {\n  // ...\n}\n```\n\nChecking thrown error is this one using `instanceof`\n\n```js\nif (err instanceof jose.errors.JWKSNoMatchingKey) {\n  // ...\n}\n```\n\n## Properties\n\n### code\n\n• **code**: `string` = `'ERR_JWKS_NO_MATCHING_KEY'`\n\nA unique error code for JWKSNoMatchingKey.\n"
  },
  {
    "path": "docs/util/errors/classes/JWKSTimeout.md",
    "content": "# Class: JWKSTimeout\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nTimeout was reached when retrieving the JWKS response.\n\n## Examples\n\nChecking thrown error is this one using a stable error code\n\n```js\nif (err.code === 'ERR_JWKS_TIMEOUT') {\n  // ...\n}\n```\n\nChecking thrown error is this one using `instanceof`\n\n```js\nif (err instanceof jose.errors.JWKSTimeout) {\n  // ...\n}\n```\n\n## Properties\n\n### code\n\n• **code**: `string` = `'ERR_JWKS_TIMEOUT'`\n\nA unique error code for JWKSTimeout.\n"
  },
  {
    "path": "docs/util/errors/classes/JWSInvalid.md",
    "content": "# Class: JWSInvalid\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAn error subclass thrown when a JWS is invalid.\n\n## Examples\n\nChecking thrown error is this one using a stable error code\n\n```js\nif (err.code === 'ERR_JWS_INVALID') {\n  // ...\n}\n```\n\nChecking thrown error is this one using `instanceof`\n\n```js\nif (err instanceof jose.errors.JWSInvalid) {\n  // ...\n}\n```\n\n## Properties\n\n### code\n\n• **code**: `string` = `'ERR_JWS_INVALID'`\n\nA unique error code for JWSInvalid.\n"
  },
  {
    "path": "docs/util/errors/classes/JWSSignatureVerificationFailed.md",
    "content": "# Class: JWSSignatureVerificationFailed\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAn error subclass thrown when JWS signature verification fails.\n\n## Examples\n\nChecking thrown error is this one using a stable error code\n\n```js\nif (err.code === 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') {\n  // ...\n}\n```\n\nChecking thrown error is this one using `instanceof`\n\n```js\nif (err instanceof jose.errors.JWSSignatureVerificationFailed) {\n  // ...\n}\n```\n\n## Properties\n\n### code\n\n• **code**: `string` = `'ERR_JWS_SIGNATURE_VERIFICATION_FAILED'`\n\nA unique error code for JWSSignatureVerificationFailed.\n"
  },
  {
    "path": "docs/util/errors/classes/JWTClaimValidationFailed.md",
    "content": "# Class: JWTClaimValidationFailed\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAn error subclass thrown when a JWT Claim Set member validation fails.\n\n## Examples\n\nChecking thrown error is this one using a stable error code\n\n```js\nif (err.code === 'ERR_JWT_CLAIM_VALIDATION_FAILED') {\n  // ...\n}\n```\n\nChecking thrown error is this one using `instanceof`\n\n```js\nif (err instanceof jose.errors.JWTClaimValidationFailed) {\n  // ...\n}\n```\n\n## Properties\n\n### claim\n\n• **claim**: `string`\n\nThe Claim for which the validation failed.\n\n***\n\n### code\n\n• **code**: `string` = `'ERR_JWT_CLAIM_VALIDATION_FAILED'`\n\nA unique error code for JWTClaimValidationFailed.\n\n***\n\n### payload\n\n• **payload**: [`JWTPayload`](../../../types/interfaces/JWTPayload.md)\n\nThe parsed JWT Claims Set (aka payload). Other JWT claims may or may not have been verified at\nthis point. The JSON Web Signature (JWS) or a JSON Web Encryption (JWE) structures' integrity\nhas however been verified. Claims Set verification happens after the JWS Signature or JWE\nDecryption processes.\n\n***\n\n### reason\n\n• **reason**: `string`\n\nReason code for the validation failure.\n"
  },
  {
    "path": "docs/util/errors/classes/JWTExpired.md",
    "content": "# Class: JWTExpired\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAn error subclass thrown when a JWT is expired.\n\n## Examples\n\nChecking thrown error is this one using a stable error code\n\n```js\nif (err.code === 'ERR_JWT_EXPIRED') {\n  // ...\n}\n```\n\nChecking thrown error is this one using `instanceof`\n\n```js\nif (err instanceof jose.errors.JWTExpired) {\n  // ...\n}\n```\n\n## Properties\n\n### claim\n\n• **claim**: `string`\n\nThe Claim for which the validation failed.\n\n***\n\n### code\n\n• **code**: `string` = `'ERR_JWT_EXPIRED'`\n\nA unique error code for JWTExpired.\n\n***\n\n### payload\n\n• **payload**: [`JWTPayload`](../../../types/interfaces/JWTPayload.md)\n\nThe parsed JWT Claims Set (aka payload). Other JWT claims may or may not have been verified at\nthis point. The JSON Web Signature (JWS) or a JSON Web Encryption (JWE) structures' integrity\nhas however been verified. Claims Set verification happens after the JWS Signature or JWE\nDecryption processes.\n\n***\n\n### reason\n\n• **reason**: `string`\n\nReason code for the validation failure.\n"
  },
  {
    "path": "docs/util/errors/classes/JWTInvalid.md",
    "content": "# Class: JWTInvalid\n\n## [💗 Help the project](https://github.com/sponsors/panva)\n\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\n\nAn error subclass thrown when a JWT is invalid.\n\n## Examples\n\nChecking thrown error is this one using a stable error code\n\n```js\nif (err.code === 'ERR_JWT_INVALID') {\n  // ...\n}\n```\n\nChecking thrown error is this one using `instanceof`\n\n```js\nif (err instanceof jose.errors.JWTInvalid) {\n  // ...\n}\n```\n\n## Properties\n\n### code\n\n• **code**: `string` = `'ERR_JWT_INVALID'`\n\nA unique error code for JWTInvalid.\n"
  },
  {
    "path": "jsr.json",
    "content": "{\n  \"$schema\": \"https://jsr.io/schema/config-file.v1.json\",\n  \"name\": \"@panva/jose\",\n  \"version\": \"6.2.2\",\n  \"exports\": {\n    \".\": \"./src/index.ts\",\n    \"./jwk/embedded\": \"./src/jwk/embedded.ts\",\n    \"./jwk/thumbprint\": \"./src/jwk/thumbprint.ts\",\n    \"./key/import\": \"./src/key/import.ts\",\n    \"./key/export\": \"./src/key/export.ts\",\n    \"./key/generate/keypair\": \"./src/key/generate_key_pair.ts\",\n    \"./key/generate/secret\": \"./src/key/generate_secret.ts\",\n    \"./jwks/remote\": \"./src/jwks/remote.ts\",\n    \"./jwks/local\": \"./src/jwks/local.ts\",\n    \"./jwt/sign\": \"./src/jwt/sign.ts\",\n    \"./jwt/verify\": \"./src/jwt/verify.ts\",\n    \"./jwt/encrypt\": \"./src/jwt/encrypt.ts\",\n    \"./jwt/decrypt\": \"./src/jwt/decrypt.ts\",\n    \"./jwt/unsecured\": \"./src/jwt/unsecured.ts\",\n    \"./jwt/decode\": \"./src/util/decode_jwt.ts\",\n    \"./decode/protected_header\": \"./src/util/decode_protected_header.ts\",\n    \"./jws/compact/sign\": \"./src/jws/compact/sign.ts\",\n    \"./jws/compact/verify\": \"./src/jws/compact/verify.ts\",\n    \"./jws/flattened/sign\": \"./src/jws/flattened/sign.ts\",\n    \"./jws/flattened/verify\": \"./src/jws/flattened/verify.ts\",\n    \"./jws/general/sign\": \"./src/jws/general/sign.ts\",\n    \"./jws/general/verify\": \"./src/jws/general/verify.ts\",\n    \"./jwe/compact/encrypt\": \"./src/jwe/compact/encrypt.ts\",\n    \"./jwe/compact/decrypt\": \"./src/jwe/compact/decrypt.ts\",\n    \"./jwe/flattened/encrypt\": \"./src/jwe/flattened/encrypt.ts\",\n    \"./jwe/flattened/decrypt\": \"./src/jwe/flattened/decrypt.ts\",\n    \"./jwe/general/encrypt\": \"./src/jwe/general/encrypt.ts\",\n    \"./jwe/general/decrypt\": \"./src/jwe/general/decrypt.ts\",\n    \"./errors\": \"./src/util/errors.ts\",\n    \"./base64url\": \"./src/util/base64url.ts\"\n  },\n  \"publish\": {\n    \"include\": [\"LICENSE.md\", \"README.md\", \"src/**/*.ts\"]\n  }\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"jose\",\n  \"version\": \"6.2.2\",\n  \"description\": \"JWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes\",\n  \"keywords\": [\n    \"akp\",\n    \"browser\",\n    \"bun\",\n    \"cloudflare\",\n    \"compact\",\n    \"decode\",\n    \"decrypt\",\n    \"deno\",\n    \"detached\",\n    \"ec\",\n    \"ecdsa\",\n    \"ed25519\",\n    \"eddsa\",\n    \"edge\",\n    \"electron\",\n    \"embedded\",\n    \"encrypt\",\n    \"flattened\",\n    \"general\",\n    \"jose\",\n    \"json web token\",\n    \"jsonwebtoken\",\n    \"jwa\",\n    \"jwe\",\n    \"jwk\",\n    \"jwks\",\n    \"jws\",\n    \"jwt-decode\",\n    \"jwt\",\n    \"ml-dsa\",\n    \"netlify\",\n    \"next\",\n    \"nextjs\",\n    \"oct\",\n    \"okp\",\n    \"payload\",\n    \"pem\",\n    \"pkcs8\",\n    \"rsa\",\n    \"sign\",\n    \"signature\",\n    \"spki\",\n    \"validate\",\n    \"vercel\",\n    \"verify\",\n    \"webcrypto\",\n    \"workerd\",\n    \"workers\",\n    \"x509\"\n  ],\n  \"homepage\": \"https://github.com/panva/jose\",\n  \"repository\": \"panva/jose\",\n  \"funding\": {\n    \"url\": \"https://github.com/sponsors/panva\"\n  },\n  \"license\": \"MIT\",\n  \"author\": \"Filip Skokan <panva.ip@gmail.com>\",\n  \"sideEffects\": false,\n  \"type\": \"module\",\n  \"imports\": {\n    \"#dist\": {\n      \"types\": \"./dist/types/index.d.ts\",\n      \"default\": \"./dist/webapi/index.js\"\n    },\n    \"#dist/*\": {\n      \"types\": \"./dist/types/*.d.ts\",\n      \"default\": \"./dist/webapi/*.js\"\n    }\n  },\n  \"exports\": {\n    \".\": {\n      \"types\": \"./dist/types/index.d.ts\",\n      \"default\": \"./dist/webapi/index.js\"\n    },\n    \"./jwk/embedded\": {\n      \"types\": \"./dist/types/jwk/embedded.d.ts\",\n      \"default\": \"./dist/webapi/jwk/embedded.js\"\n    },\n    \"./jwk/thumbprint\": {\n      \"types\": \"./dist/types/jwk/thumbprint.d.ts\",\n      \"default\": \"./dist/webapi/jwk/thumbprint.js\"\n    },\n    \"./key/import\": {\n      \"types\": \"./dist/types/key/import.d.ts\",\n      \"default\": \"./dist/webapi/key/import.js\"\n    },\n    \"./key/export\": {\n      \"types\": \"./dist/types/key/export.d.ts\",\n      \"default\": \"./dist/webapi/key/export.js\"\n    },\n    \"./key/generate/keypair\": {\n      \"types\": \"./dist/types/key/generate_key_pair.d.ts\",\n      \"default\": \"./dist/webapi/key/generate_key_pair.js\"\n    },\n    \"./key/generate/secret\": {\n      \"types\": \"./dist/types/key/generate_secret.d.ts\",\n      \"default\": \"./dist/webapi/key/generate_secret.js\"\n    },\n    \"./jwks/remote\": {\n      \"types\": \"./dist/types/jwks/remote.d.ts\",\n      \"default\": \"./dist/webapi/jwks/remote.js\"\n    },\n    \"./jwks/local\": {\n      \"types\": \"./dist/types/jwks/local.d.ts\",\n      \"default\": \"./dist/webapi/jwks/local.js\"\n    },\n    \"./jwt/sign\": {\n      \"types\": \"./dist/types/jwt/sign.d.ts\",\n      \"default\": \"./dist/webapi/jwt/sign.js\"\n    },\n    \"./jwt/verify\": {\n      \"types\": \"./dist/types/jwt/verify.d.ts\",\n      \"default\": \"./dist/webapi/jwt/verify.js\"\n    },\n    \"./jwt/encrypt\": {\n      \"types\": \"./dist/types/jwt/encrypt.d.ts\",\n      \"default\": \"./dist/webapi/jwt/encrypt.js\"\n    },\n    \"./jwt/decrypt\": {\n      \"types\": \"./dist/types/jwt/decrypt.d.ts\",\n      \"default\": \"./dist/webapi/jwt/decrypt.js\"\n    },\n    \"./jwt/unsecured\": {\n      \"types\": \"./dist/types/jwt/unsecured.d.ts\",\n      \"default\": \"./dist/webapi/jwt/unsecured.js\"\n    },\n    \"./jwt/decode\": {\n      \"types\": \"./dist/types/util/decode_jwt.d.ts\",\n      \"default\": \"./dist/webapi/util/decode_jwt.js\"\n    },\n    \"./decode/protected_header\": {\n      \"types\": \"./dist/types/util/decode_protected_header.d.ts\",\n      \"default\": \"./dist/webapi/util/decode_protected_header.js\"\n    },\n    \"./jws/compact/sign\": {\n      \"types\": \"./dist/types/jws/compact/sign.d.ts\",\n      \"default\": \"./dist/webapi/jws/compact/sign.js\"\n    },\n    \"./jws/compact/verify\": {\n      \"types\": \"./dist/types/jws/compact/verify.d.ts\",\n      \"default\": \"./dist/webapi/jws/compact/verify.js\"\n    },\n    \"./jws/flattened/sign\": {\n      \"types\": \"./dist/types/jws/flattened/sign.d.ts\",\n      \"default\": \"./dist/webapi/jws/flattened/sign.js\"\n    },\n    \"./jws/flattened/verify\": {\n      \"types\": \"./dist/types/jws/flattened/verify.d.ts\",\n      \"default\": \"./dist/webapi/jws/flattened/verify.js\"\n    },\n    \"./jws/general/sign\": {\n      \"types\": \"./dist/types/jws/general/sign.d.ts\",\n      \"default\": \"./dist/webapi/jws/general/sign.js\"\n    },\n    \"./jws/general/verify\": {\n      \"types\": \"./dist/types/jws/general/verify.d.ts\",\n      \"default\": \"./dist/webapi/jws/general/verify.js\"\n    },\n    \"./jwe/compact/encrypt\": {\n      \"types\": \"./dist/types/jwe/compact/encrypt.d.ts\",\n      \"default\": \"./dist/webapi/jwe/compact/encrypt.js\"\n    },\n    \"./jwe/compact/decrypt\": {\n      \"types\": \"./dist/types/jwe/compact/decrypt.d.ts\",\n      \"default\": \"./dist/webapi/jwe/compact/decrypt.js\"\n    },\n    \"./jwe/flattened/encrypt\": {\n      \"types\": \"./dist/types/jwe/flattened/encrypt.d.ts\",\n      \"default\": \"./dist/webapi/jwe/flattened/encrypt.js\"\n    },\n    \"./jwe/flattened/decrypt\": {\n      \"types\": \"./dist/types/jwe/flattened/decrypt.d.ts\",\n      \"default\": \"./dist/webapi/jwe/flattened/decrypt.js\"\n    },\n    \"./jwe/general/encrypt\": {\n      \"types\": \"./dist/types/jwe/general/encrypt.d.ts\",\n      \"default\": \"./dist/webapi/jwe/general/encrypt.js\"\n    },\n    \"./jwe/general/decrypt\": {\n      \"types\": \"./dist/types/jwe/general/decrypt.d.ts\",\n      \"default\": \"./dist/webapi/jwe/general/decrypt.js\"\n    },\n    \"./errors\": {\n      \"types\": \"./dist/types/util/errors.d.ts\",\n      \"default\": \"./dist/webapi/util/errors.js\"\n    },\n    \"./base64url\": {\n      \"types\": \"./dist/types/util/base64url.d.ts\",\n      \"default\": \"./dist/webapi/util/base64url.js\"\n    },\n    \"./package.json\": \"./package.json\"\n  },\n  \"main\": \"./dist/webapi/index.js\",\n  \"types\": \"./dist/types/index.d.ts\",\n  \"files\": [\n    \"dist/webapi/**/*.js\",\n    \"dist/types/**/*.d.ts\",\n    \"!dist/**/*.bundle.js\",\n    \"!dist/**/*.umd.js\",\n    \"!dist/**/*.min.js\",\n    \"!dist/types/runtime/*\",\n    \"!dist/types/lib/*\",\n    \"!dist/deno/**/*\"\n  ],\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"build-all\": \"run-s clear build build:*\",\n    \"build:bundle\": \"esbuild --bundle dist/webapi/index.js --format=esm --target=es2022 --outfile=dist/webapi/index.bundle.js\",\n    \"build:bundle-min\": \"esbuild --minify --bundle dist/webapi/index.js --format=esm --target=es2022 --outfile=dist/webapi/index.bundle.min.js\",\n    \"build:umd\": \"rollup dist/webapi/index.bundle.js --format umd --name jose -o dist/webapi/index.umd.js && rollup dist/webapi/index.bundle.min.js --compact --format umd --name jose -o dist/webapi/index.umd.min.js\",\n    \"build:deno\": \"mkdir -p dist/deno && cp -R src/. dist/deno && find dist/deno -name '*.ts' -type f -print0 | xargs -0 sed -i.bak -e \\\"s/\\\\.js'/.ts'/g\\\" && npm run sedcleanup\",\n    \"build:types\": \"npm run build -- -p ./tsconfig/types.json && cd src && find . -name '*.d.ts' -maxdepth 2 -type f -exec rsync -R \\\"{}\\\" ../dist/types  \\\\;\",\n    \"build:jsr\": \"npx --yes jsr publish --dry-run --allow-dirty\",\n    \"clear\": \"rm -Rf dist\",\n    \"sedcleanup\": \"find . -name '*.bak' -type f -print0 | xargs -0 rm -f\",\n    \"docs:generate\": \"typedoc\",\n    \"types:find\": \"find dist/types -name '*.d.ts' -type f -print0\",\n    \"test\": \"bash -c 'source .node_flags.sh && ava'\",\n    \"format\": \"prettier --log-level silent --write ./test ./tap ./src ./tools ./cookbook ./tsconfig\",\n    \"tap:browsers\": \"./tap/.browsers.sh\",\n    \"tap:bun\": \"./tap/.bun.sh\",\n    \"tap:deno\": \"./tap/.deno.sh\",\n    \"tap:electron\": \"./tap/.electron.sh\",\n    \"tap:node\": \"bash -c './tap/.node.sh'\",\n    \"tap:workerd\": \"./tap/.workerd.sh\"\n  },\n  \"devDependencies\": {\n    \"@playwright/test\": \"^1.58.2\",\n    \"@types/node\": \"^24.12.0\",\n    \"@types/qunit\": \"^2.19.13\",\n    \"ava\": \"^7.0.0\",\n    \"esbuild\": \"^0.27.4\",\n    \"glob\": \"^13.0.6\",\n    \"npm-run-all2\": \"^8.0.4\",\n    \"patch-package\": \"^8.0.1\",\n    \"prettier\": \"^3.8.1\",\n    \"prettier-plugin-jsdoc\": \"^1.8.0\",\n    \"qunit\": \"^2.25.0\",\n    \"rollup\": \"^4.59.0\",\n    \"tar\": \"^7.5.11\",\n    \"timekeeper\": \"^2.3.1\",\n    \"tsx\": \"^4.21.0\",\n    \"typedoc\": \"^0.28.17\",\n    \"typedoc-plugin-markdown\": \"^4.11.0\",\n    \"typedoc-plugin-mdn-links\": \"^5.1.1\",\n    \"typescript\": \"^5.9.3\",\n    \"undici\": \"^7.24.4\"\n  }\n}\n"
  },
  {
    "path": "patches/typedoc-plugin-markdown+4.11.0.patch",
    "content": "diff --git a/node_modules/typedoc-plugin-markdown/dist/libs/utils/escape-chars.js b/node_modules/typedoc-plugin-markdown/dist/libs/utils/escape-chars.js\nindex e29ab44..38f70d5 100644\n--- a/node_modules/typedoc-plugin-markdown/dist/libs/utils/escape-chars.js\n+++ b/node_modules/typedoc-plugin-markdown/dist/libs/utils/escape-chars.js\n@@ -5,7 +5,7 @@ export function escapeChars(str) {\n         .replace(/{/g, '\\\\{')\n         .replace(/}/g, '\\\\}')\n         .replace(/_/g, '\\\\_')\n-        .replace(/`/g, '\\\\`')\n+        // .replace(/`/g, '\\\\`')\n         .replace(/\\|/g, '\\\\|')\n         .replace(/\\[/g, '\\\\[')\n         .replace(/\\]/g, '\\\\]')\ndiff --git a/node_modules/typedoc-plugin-markdown/dist/theme/context/helpers/get-project-name.js b/node_modules/typedoc-plugin-markdown/dist/theme/context/helpers/get-project-name.js\nindex 1c71dae..c031a54 100644\n--- a/node_modules/typedoc-plugin-markdown/dist/theme/context/helpers/get-project-name.js\n+++ b/node_modules/typedoc-plugin-markdown/dist/theme/context/helpers/get-project-name.js\n@@ -4,6 +4,6 @@ export function getProjectName(stringWithPlaceholders, page, includeVersion = tr\n         .replace('{version}', includeVersion && page.project.packageVersion\n         ? `v${page.project.packageVersion}`\n         : '')\n-        .replace(/\\s+/g, ' ')\n+        // .replace(/\\s+/g, ' ')\n         .trim();\n }\ndiff --git a/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.declarationTitle.js b/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.declarationTitle.js\nindex ee29ee7..9589eae 100644\n--- a/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.declarationTitle.js\n+++ b/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.declarationTitle.js\n@@ -26,7 +26,7 @@ export function declarationTitle(model) {\n         md.push(';');\n     }\n     const result = md.join('');\n-    return useCodeBlocks ? codeBlock(result) : `> ${result}`;\n+    return useCodeBlocks ? codeBlock(result) : `• ${result}`;\n }\n function getPrefix(context, model, useCodeBlocks) {\n     const keyword = context.helpers.getKeyword(model.kind);\ndiff --git a/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.hierarchy.js b/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.hierarchy.js\nindex b1d7fd3..b23a8da 100644\n--- a/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.hierarchy.js\n+++ b/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.hierarchy.js\n@@ -1,6 +1,7 @@\n import { heading, unorderedList } from '../../../libs/markdown/index.js';\n import { i18n } from 'typedoc';\n export function hierarchy(model, options) {\n+    return '';\n     const md = [];\n     const getHierarchy = (hModel) => {\n         const parent = !hModel.isTarget\ndiff --git a/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.inheritance.js b/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.inheritance.js\nindex 29eaa2b..c0c0f6c 100644\n--- a/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.inheritance.js\n+++ b/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.inheritance.js\n@@ -1,6 +1,7 @@\n import { heading } from '../../../libs/markdown/index.js';\n import { i18n } from 'typedoc';\n export function inheritance(model, options) {\n+    return '';\n     const md = [];\n     if (model.implementationOf) {\n         if (options.headingLevel !== -1) {\ndiff --git a/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.memberWithGroups.js b/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.memberWithGroups.js\nindex c2aab7d..fe6daf9 100644\n--- a/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.memberWithGroups.js\n+++ b/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.memberWithGroups.js\n@@ -42,7 +42,7 @@ export function memberWithGroups(model, options) {\n             }));\n         }\n     }\n-    if (model.implementedTypes?.length) {\n+    if (false) {\n         md.push(heading(options.headingLevel, i18n.theme_implements()));\n         md.push(unorderedList(model.implementedTypes.map((implementedType) => this.partials.someType(implementedType))));\n     }\ndiff --git a/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.signatureTitle.js b/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.signatureTitle.js\nindex cbc03e8..5fe0813 100644\n--- a/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.signatureTitle.js\n+++ b/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/member.signatureTitle.js\n@@ -38,5 +38,5 @@ export function signatureTitle(model, options) {\n         md.push(';');\n     }\n     const result = md.join('');\n-    return useCodeBlocks ? codeBlock(result) : `> ${result}`;\n+    return useCodeBlocks ? codeBlock(result) : `▸ ${result}`;\n }\ndiff --git a/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/page.pageTitle.js b/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/page.pageTitle.js\nindex 1df516f..9ce6394 100644\n--- a/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/page.pageTitle.js\n+++ b/node_modules/typedoc-plugin-markdown/dist/theme/context/partials/page.pageTitle.js\n@@ -117,6 +117,6 @@ function getFromString(textContent, config) {\n         .replace('{codeKeyword}', config.codeKeyword ?? '')\n         .replace('{group}', config.group ?? '')\n         .replace(/``/g, '')\n-        .replace(/\\s+/g, ' ')\n+        // .replace(/\\s+/g, ' ')\n         .trim();\n }\n"
  },
  {
    "path": "patches/typedoc-plugin-mdn-links+5.1.1.patch",
    "content": "diff --git a/node_modules/typedoc-plugin-mdn-links/data/web-api.json b/node_modules/typedoc-plugin-mdn-links/data/web-api.json\nindex edf887d..8da4c95 100644\n--- a/node_modules/typedoc-plugin-mdn-links/data/web-api.json\n+++ b/node_modules/typedoc-plugin-mdn-links/data/web-api.json\n@@ -1,4 +1,19 @@\n {\n+\t\"createPublicKey\": {\n+\t\t\"url\": \"https://nodejs.org/api/crypto.html#cryptocreatepublickeykey\"\n+\t},\n+\t\"createPrivateKey\": {\n+\t\t\"url\": \"https://nodejs.org/api/crypto.html#cryptocreateprivatekeykey\"\n+\t},\n+\t\"createSecretKey\": {\n+\t\t\"url\": \"https://nodejs.org/api/crypto.html#cryptocreatesecretkeykey-encoding\"\n+\t},\n+\t\"KeyObject\": {\n+\t\t\"url\": \"https://nodejs.org/api/crypto.html#class-keyobject\"\n+\t},\n+\t\"Buffer\": {\n+\t\t\"url\": \"https://nodejs.org/api/buffer.html#class-buffer\"\n+\t},\n \t\"ANGLE_instanced_arrays\": {\n \t\t\"url\": \"https://developer.mozilla.org/docs/Web/API/ANGLE_instanced_arrays\",\n \t\t\"inst\": {\n"
  },
  {
    "path": "playwright.config.ts",
    "content": "import { defineConfig, devices } from '@playwright/test'\n\nexport default defineConfig({\n  testDir: './tap',\n  testMatch: '.browser.ts',\n  timeout: 120_000,\n  projects: [\n    { name: 'chromium', use: devices['Desktop Chrome'] },\n    { name: 'firefox', use: devices['Desktop Firefox'] },\n    { name: 'safari', use: devices['Desktop Safari'] },\n  ],\n})\n"
  },
  {
    "path": "src/index.ts",
    "content": "export { compactDecrypt } from './jwe/compact/decrypt.js'\nexport type { CompactDecryptGetKey } from './jwe/compact/decrypt.js'\nexport { flattenedDecrypt } from './jwe/flattened/decrypt.js'\nexport type { FlattenedDecryptGetKey } from './jwe/flattened/decrypt.js'\nexport { generalDecrypt } from './jwe/general/decrypt.js'\nexport type { GeneralDecryptGetKey } from './jwe/general/decrypt.js'\nexport { GeneralEncrypt } from './jwe/general/encrypt.js'\nexport type { Recipient } from './jwe/general/encrypt.js'\n\nexport { compactVerify } from './jws/compact/verify.js'\nexport type { CompactVerifyGetKey } from './jws/compact/verify.js'\nexport { flattenedVerify } from './jws/flattened/verify.js'\nexport type { FlattenedVerifyGetKey } from './jws/flattened/verify.js'\nexport { generalVerify } from './jws/general/verify.js'\nexport type { GeneralVerifyGetKey } from './jws/general/verify.js'\n\nexport { jwtVerify } from './jwt/verify.js'\nexport type { JWTVerifyOptions, JWTVerifyGetKey } from './jwt/verify.js'\nexport { jwtDecrypt } from './jwt/decrypt.js'\nexport type { JWTDecryptOptions, JWTDecryptGetKey } from './jwt/decrypt.js'\n\nexport { CompactEncrypt } from './jwe/compact/encrypt.js'\nexport { FlattenedEncrypt } from './jwe/flattened/encrypt.js'\n\nexport { CompactSign } from './jws/compact/sign.js'\nexport { FlattenedSign } from './jws/flattened/sign.js'\nexport { GeneralSign } from './jws/general/sign.js'\nexport type { Signature } from './jws/general/sign.js'\n\nexport { SignJWT } from './jwt/sign.js'\nexport { EncryptJWT } from './jwt/encrypt.js'\n\nexport { calculateJwkThumbprint, calculateJwkThumbprintUri } from './jwk/thumbprint.js'\nexport { EmbeddedJWK } from './jwk/embedded.js'\n\nexport { createLocalJWKSet } from './jwks/local.js'\nexport { createRemoteJWKSet, jwksCache, customFetch } from './jwks/remote.js'\nexport type {\n  RemoteJWKSetOptions,\n  JWKSCacheInput,\n  ExportedJWKSCache,\n  FetchImplementation,\n} from './jwks/remote.js'\n\nexport { UnsecuredJWT } from './jwt/unsecured.js'\nexport type { UnsecuredResult } from './jwt/unsecured.js'\n\nexport { exportPKCS8, exportSPKI, exportJWK } from './key/export.js'\n\nexport { importSPKI, importPKCS8, importX509, importJWK } from './key/import.js'\nexport type { KeyImportOptions } from './key/import.js'\n\nexport { decodeProtectedHeader } from './util/decode_protected_header.js'\nexport { decodeJwt } from './util/decode_jwt.js'\nexport type { ProtectedHeaderParameters } from './util/decode_protected_header.js'\n\nimport * as errors from './util/errors.js'\nexport { errors }\n\nexport { generateKeyPair } from './key/generate_key_pair.js'\nexport type { GenerateKeyPairResult, GenerateKeyPairOptions } from './key/generate_key_pair.js'\nexport { generateSecret } from './key/generate_secret.js'\nexport type { GenerateSecretOptions } from './key/generate_secret.js'\n\nimport * as base64url from './util/base64url.js'\nexport { base64url }\n\nexport type {\n  CompactDecryptResult,\n  CompactJWEHeaderParameters,\n  CompactJWSHeaderParameters,\n  CompactVerifyResult,\n  CritOption,\n  CryptoKey,\n  DecryptOptions,\n  EncryptOptions,\n  FlattenedDecryptResult,\n  FlattenedJWE,\n  FlattenedJWS,\n  FlattenedJWSInput,\n  FlattenedVerifyResult,\n  GeneralDecryptResult,\n  GeneralJWE,\n  GeneralJWS,\n  GeneralJWSInput,\n  GeneralVerifyResult,\n  GetKeyFunction,\n  JoseHeaderParameters,\n  JSONWebKeySet,\n  JWEHeaderParameters,\n  JWEKeyManagementHeaderParameters,\n  JWK_EC_Private,\n  JWK_EC_Public,\n  JWK_oct,\n  JWK_OKP_Private,\n  JWK_OKP_Public,\n  JWK_RSA_Private,\n  JWK_RSA_Public,\n  JWK,\n  JWKParameters,\n  JWSHeaderParameters,\n  JWTClaimVerificationOptions,\n  JWTDecryptResult,\n  JWTHeaderParameters,\n  JWTPayload,\n  JWTVerifyResult,\n  KeyObject,\n  ProduceJWT,\n  ResolvedKey,\n  SignOptions,\n  VerifyOptions,\n} from './types.d.ts'\n\n/**\n * In prior releases this indicated whether a Node.js-specific build was loaded, this is now fixed\n * to `\"WebCryptoAPI\"`\n *\n * @deprecated\n */\nexport const cryptoRuntime = 'WebCryptoAPI'\n"
  },
  {
    "path": "src/jwe/compact/decrypt.ts",
    "content": "/**\n * Decrypting JSON Web Encryption (JWE) in Compact Serialization\n *\n * @module\n */\n\nimport { flattenedDecrypt } from '../flattened/decrypt.js'\nimport { JWEInvalid } from '../../util/errors.js'\nimport { decoder } from '../../lib/buffer_utils.js'\nimport type * as types from '../../types.d.ts'\n\n/**\n * Interface for Compact JWE Decryption dynamic key resolution. No token components have been\n * verified at the time of this function call.\n */\nexport interface CompactDecryptGetKey extends types.GetKeyFunction<\n  types.CompactJWEHeaderParameters,\n  types.FlattenedJWE\n> {}\n\n/**\n * Decrypts a Compact JWE.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/jwe/compact/decrypt'`.\n *\n * @example\n *\n * ```js\n * const jwe =\n *   'eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0.nyQ19eq9ogh9wA7fFtnI2oouzy5_8b5DeLkoRMfi2yijgfTs2zEnayCEofz_qhnL-nwszabd9qUeHv0-IwvhhJJS7GUJOU3ikiIe42qcIAFme1A_Fo9CTxw4XTOy-I5qanl8So91u6hwfyN1VxAqVLsSE7_23EC-gfGEg_5znew9PyXXsOIE-K_HH7IQowRrlZ1X_bM_Liu53RzDpLDvRz59mp3S8L56YqpM8FexFGTGpEaoTcEIst375qncYt3-79IVR7gZN1RWsWgjPatfvVbnh74PglQcATSf3UUhaW0OAKn6q7r3PDx6DIKQ35bgHQg5QopuN00eIfLQL2trGw.W3grIVj5HVuAb76X.6PcuDe5D6ttWFYyv0oqqdDXfI2R8wBg1F2Q80UUA_Gv8eEimNWfxIWdLxrjzgQGSvIhxmFKuLM0.a93_Ug3uZHuczj70Zavx8Q'\n *\n * const { plaintext, protectedHeader } = await jose.compactDecrypt(jwe, privateKey)\n *\n * console.log(protectedHeader)\n * console.log(new TextDecoder().decode(plaintext))\n * ```\n *\n * @param jwe Compact JWE.\n * @param key Private Key or Secret to decrypt the JWE with. See\n *   {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}.\n * @param options JWE Decryption options.\n */\nexport async function compactDecrypt(\n  jwe: string | Uint8Array,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n  options?: types.DecryptOptions,\n): Promise<types.CompactDecryptResult>\n/**\n * @param jwe Compact JWE.\n * @param getKey Function resolving Private Key or Secret to decrypt the JWE with. See\n *   {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}.\n * @param options JWE Decryption options.\n */\nexport async function compactDecrypt(\n  jwe: string | Uint8Array,\n  getKey: CompactDecryptGetKey,\n  options?: types.DecryptOptions,\n): Promise<types.CompactDecryptResult & types.ResolvedKey>\nexport async function compactDecrypt(\n  jwe: string | Uint8Array,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array | CompactDecryptGetKey,\n  options?: types.DecryptOptions,\n) {\n  if (jwe instanceof Uint8Array) {\n    jwe = decoder.decode(jwe)\n  }\n\n  if (typeof jwe !== 'string') {\n    throw new JWEInvalid('Compact JWE must be a string or Uint8Array')\n  }\n  const {\n    0: protectedHeader,\n    1: encryptedKey,\n    2: iv,\n    3: ciphertext,\n    4: tag,\n    length,\n  } = jwe.split('.')\n\n  if (length !== 5) {\n    throw new JWEInvalid('Invalid Compact JWE')\n  }\n\n  const decrypted = await flattenedDecrypt(\n    {\n      ciphertext,\n      iv: iv || undefined,\n      protected: protectedHeader,\n      tag: tag || undefined,\n      encrypted_key: encryptedKey || undefined,\n    },\n    key as Parameters<typeof flattenedDecrypt>[1],\n    options,\n  )\n\n  const result = { plaintext: decrypted.plaintext, protectedHeader: decrypted.protectedHeader! }\n\n  if (typeof key === 'function') {\n    return { ...result, key: decrypted.key }\n  }\n\n  return result\n}\n"
  },
  {
    "path": "src/jwe/compact/encrypt.ts",
    "content": "/**\n * Encrypting JSON Web Encryption (JWE) in Compact Serialization\n *\n * @module\n */\n\nimport type * as types from '../../types.d.ts'\nimport { FlattenedEncrypt } from '../flattened/encrypt.js'\n\n/**\n * The CompactEncrypt class is used to build and encrypt Compact JWE strings.\n *\n * This class is exported (as a named export) from the main `'jose'` module entry point as well as\n * from its subpath export `'jose/jwe/compact/encrypt'`.\n *\n * @example\n *\n * ```js\n * const jwe = await new jose.CompactEncrypt(\n *   new TextEncoder().encode('It’s a dangerous business, Frodo, going out your door.'),\n * )\n *   .setProtectedHeader({ alg: 'RSA-OAEP-256', enc: 'A256GCM' })\n *   .encrypt(publicKey)\n *\n * console.log(jwe)\n * ```\n */\nexport class CompactEncrypt {\n  #flattened: FlattenedEncrypt\n\n  /**\n   * {@link CompactEncrypt} constructor\n   *\n   * @param plaintext Binary representation of the plaintext to encrypt.\n   */\n  constructor(plaintext: Uint8Array) {\n    this.#flattened = new FlattenedEncrypt(plaintext)\n  }\n\n  /**\n   * Sets a content encryption key to use, by default a random suitable one is generated for the JWE\n   * enc\" (Encryption Algorithm) Header Parameter.\n   *\n   * @deprecated You should not use this method. It is only really intended for test and vector\n   *   validation purposes.\n   *\n   * @param cek JWE Content Encryption Key.\n   */\n  setContentEncryptionKey(cek: Uint8Array): this {\n    this.#flattened.setContentEncryptionKey(cek)\n    return this\n  }\n\n  /**\n   * Sets the JWE Initialization Vector to use for content encryption, by default a random suitable\n   * one is generated for the JWE enc\" (Encryption Algorithm) Header Parameter.\n   *\n   * @deprecated You should not use this method. It is only really intended for test and vector\n   *   validation purposes.\n   *\n   * @param iv JWE Initialization Vector.\n   */\n  setInitializationVector(iv: Uint8Array): this {\n    this.#flattened.setInitializationVector(iv)\n    return this\n  }\n\n  /**\n   * Sets the JWE Protected Header on the CompactEncrypt object.\n   *\n   * @param protectedHeader JWE Protected Header object.\n   */\n  setProtectedHeader(protectedHeader: types.CompactJWEHeaderParameters): this {\n    this.#flattened.setProtectedHeader(protectedHeader)\n    return this\n  }\n\n  /**\n   * Sets the JWE Key Management parameters to be used when encrypting.\n   *\n   * (ECDH-ES) Use of this method is needed for ECDH based algorithms to set the \"apu\" (Agreement\n   * PartyUInfo) or \"apv\" (Agreement PartyVInfo) parameters.\n   *\n   * @param parameters JWE Key Management parameters.\n   */\n  setKeyManagementParameters(parameters: types.JWEKeyManagementHeaderParameters): this {\n    this.#flattened.setKeyManagementParameters(parameters)\n    return this\n  }\n\n  /**\n   * Encrypts and resolves the value of the Compact JWE string.\n   *\n   * @param key Public Key or Secret to encrypt the JWE with. See\n   *   {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}.\n   * @param options JWE Encryption options.\n   */\n  async encrypt(\n    key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n    options?: types.EncryptOptions,\n  ): Promise<string> {\n    const jwe = await this.#flattened.encrypt(key, options)\n\n    return [jwe.protected, jwe.encrypted_key, jwe.iv, jwe.ciphertext, jwe.tag].join('.')\n  }\n}\n"
  },
  {
    "path": "src/jwe/flattened/decrypt.ts",
    "content": "/**\n * Decrypting JSON Web Encryption (JWE) in Flattened JSON Serialization\n *\n * @module\n */\n\nimport type * as types from '../../types.d.ts'\nimport { decode as b64u } from '../../util/base64url.js'\nimport { decrypt } from '../../lib/content_encryption.js'\nimport { decodeBase64url } from '../../lib/helpers.js'\nimport { JOSEAlgNotAllowed, JOSENotSupported, JWEInvalid } from '../../util/errors.js'\nimport { isDisjoint } from '../../lib/type_checks.js'\nimport { isObject } from '../../lib/type_checks.js'\nimport { decryptKeyManagement } from '../../lib/key_management.js'\nimport { decoder, concat, encode } from '../../lib/buffer_utils.js'\nimport { generateCek } from '../../lib/content_encryption.js'\nimport { validateCrit } from '../../lib/validate_crit.js'\nimport { validateAlgorithms } from '../../lib/validate_algorithms.js'\nimport { normalizeKey } from '../../lib/normalize_key.js'\nimport { checkKeyType } from '../../lib/check_key_type.js'\nimport { decompress } from '../../lib/deflate.js'\n\n/**\n * Interface for Flattened JWE Decryption dynamic key resolution. No token components have been\n * verified at the time of this function call.\n */\nexport interface FlattenedDecryptGetKey extends types.GetKeyFunction<\n  types.JWEHeaderParameters | undefined,\n  types.FlattenedJWE\n> {}\n\n/**\n * Decrypts a Flattened JWE.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/jwe/flattened/decrypt'`.\n *\n * @example\n *\n * ```js\n * const jwe = {\n *   ciphertext: '9EzjFISUyoG-ifC2mSihfP0DPC80yeyrxhTzKt1C_VJBkxeBG0MI4Te61Pk45RAGubUvBpU9jm4',\n *   iv: '8Fy7A_IuoX5VXG9s',\n *   tag: 'W76IYV6arGRuDSaSyWrQNg',\n *   encrypted_key:\n *     'Z6eD4UK_yFb5ZoKvKkGAdqywEG_m0e4IYo0x8Vf30LAMJcsc-_zSgIeiF82teZyYi2YYduHKoqImk7MRnoPZOlEs0Q5BNK1OgBmSOhCE8DFyqh9Zh48TCTP6lmBQ52naqoUJFMtHzu-0LwZH26hxos0GP3Dt19O379MJB837TdKKa87skq0zHaVLAquRHOBF77GI54Bc7O49d8aOrSu1VEFGMThlW2caspPRiTSePDMDPq7_WGk50izRhB3Asl9wmP9wEeaTrkJKRnQj5ips1SAZ1hDBsqEQKKukxP1HtdcopHV5_qgwU8Hjm5EwSLMluMQuiE6hwlkXGOujZLVizA',\n *   aad: 'VGhlIEZlbGxvd3NoaXAgb2YgdGhlIFJpbmc',\n *   protected: 'eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0',\n * }\n *\n * const { plaintext, protectedHeader, additionalAuthenticatedData } =\n *   await jose.flattenedDecrypt(jwe, privateKey)\n *\n * console.log(protectedHeader)\n * const decoder = new TextDecoder()\n * console.log(decoder.decode(plaintext))\n * console.log(decoder.decode(additionalAuthenticatedData))\n * ```\n *\n * @param jwe Flattened JWE.\n * @param key Private Key or Secret to decrypt the JWE with. See\n *   {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}.\n * @param options JWE Decryption options.\n */\nexport function flattenedDecrypt(\n  jwe: types.FlattenedJWE,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n  options?: types.DecryptOptions,\n): Promise<types.FlattenedDecryptResult>\n/**\n * @param jwe Flattened JWE.\n * @param getKey Function resolving Private Key or Secret to decrypt the JWE with. See\n *   {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}.\n * @param options JWE Decryption options.\n */\nexport function flattenedDecrypt(\n  jwe: types.FlattenedJWE,\n  getKey: FlattenedDecryptGetKey,\n  options?: types.DecryptOptions,\n): Promise<types.FlattenedDecryptResult & types.ResolvedKey>\nexport async function flattenedDecrypt(\n  jwe: types.FlattenedJWE,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array | FlattenedDecryptGetKey,\n  options?: types.DecryptOptions,\n) {\n  if (!isObject(jwe)) {\n    throw new JWEInvalid('Flattened JWE must be an object')\n  }\n\n  if (jwe.protected === undefined && jwe.header === undefined && jwe.unprotected === undefined) {\n    throw new JWEInvalid('JOSE Header missing')\n  }\n\n  if (jwe.iv !== undefined && typeof jwe.iv !== 'string') {\n    throw new JWEInvalid('JWE Initialization Vector incorrect type')\n  }\n\n  if (typeof jwe.ciphertext !== 'string') {\n    throw new JWEInvalid('JWE Ciphertext missing or incorrect type')\n  }\n\n  if (jwe.tag !== undefined && typeof jwe.tag !== 'string') {\n    throw new JWEInvalid('JWE Authentication Tag incorrect type')\n  }\n\n  if (jwe.protected !== undefined && typeof jwe.protected !== 'string') {\n    throw new JWEInvalid('JWE Protected Header incorrect type')\n  }\n\n  if (jwe.encrypted_key !== undefined && typeof jwe.encrypted_key !== 'string') {\n    throw new JWEInvalid('JWE Encrypted Key incorrect type')\n  }\n\n  if (jwe.aad !== undefined && typeof jwe.aad !== 'string') {\n    throw new JWEInvalid('JWE AAD incorrect type')\n  }\n\n  if (jwe.header !== undefined && !isObject(jwe.header)) {\n    throw new JWEInvalid('JWE Shared Unprotected Header incorrect type')\n  }\n\n  if (jwe.unprotected !== undefined && !isObject(jwe.unprotected)) {\n    throw new JWEInvalid('JWE Per-Recipient Unprotected Header incorrect type')\n  }\n\n  let parsedProt!: types.JWEHeaderParameters | undefined\n  if (jwe.protected) {\n    try {\n      const protectedHeader = b64u(jwe.protected)\n      parsedProt = JSON.parse(decoder.decode(protectedHeader))\n    } catch {\n      throw new JWEInvalid('JWE Protected Header is invalid')\n    }\n  }\n  if (!isDisjoint(parsedProt, jwe.header, jwe.unprotected)) {\n    throw new JWEInvalid(\n      'JWE Protected, JWE Unprotected Header, and JWE Per-Recipient Unprotected Header Parameter names must be disjoint',\n    )\n  }\n\n  const joseHeader: types.JWEHeaderParameters = {\n    ...parsedProt,\n    ...jwe.header,\n    ...jwe.unprotected,\n  }\n\n  validateCrit(JWEInvalid, new Map(), options?.crit, parsedProt, joseHeader)\n\n  if (joseHeader.zip !== undefined && joseHeader.zip !== 'DEF') {\n    throw new JOSENotSupported(\n      'Unsupported JWE \"zip\" (Compression Algorithm) Header Parameter value.',\n    )\n  }\n\n  if (joseHeader.zip !== undefined && !parsedProt?.zip) {\n    throw new JWEInvalid(\n      'JWE \"zip\" (Compression Algorithm) Header Parameter MUST be in a protected header.',\n    )\n  }\n\n  const { alg, enc } = joseHeader\n\n  if (typeof alg !== 'string' || !alg) {\n    throw new JWEInvalid('missing JWE Algorithm (alg) in JWE Header')\n  }\n\n  if (typeof enc !== 'string' || !enc) {\n    throw new JWEInvalid('missing JWE Encryption Algorithm (enc) in JWE Header')\n  }\n\n  const keyManagementAlgorithms =\n    options && validateAlgorithms('keyManagementAlgorithms', options.keyManagementAlgorithms)\n  const contentEncryptionAlgorithms =\n    options &&\n    validateAlgorithms('contentEncryptionAlgorithms', options.contentEncryptionAlgorithms)\n\n  if (\n    (keyManagementAlgorithms && !keyManagementAlgorithms.has(alg)) ||\n    (!keyManagementAlgorithms && alg.startsWith('PBES2'))\n  ) {\n    throw new JOSEAlgNotAllowed('\"alg\" (Algorithm) Header Parameter value not allowed')\n  }\n\n  if (contentEncryptionAlgorithms && !contentEncryptionAlgorithms.has(enc)) {\n    throw new JOSEAlgNotAllowed('\"enc\" (Encryption Algorithm) Header Parameter value not allowed')\n  }\n\n  let encryptedKey!: Uint8Array\n  if (jwe.encrypted_key !== undefined) {\n    encryptedKey = decodeBase64url(jwe.encrypted_key!, 'encrypted_key', JWEInvalid)\n  }\n\n  let resolvedKey = false\n  if (typeof key === 'function') {\n    key = await key(parsedProt, jwe)\n    resolvedKey = true\n  }\n  checkKeyType(alg === 'dir' ? enc : alg, key, 'decrypt')\n\n  const k = await normalizeKey(key, alg)\n  let cek: types.CryptoKey | Uint8Array\n  try {\n    cek = await decryptKeyManagement(alg, k, encryptedKey, joseHeader, options)\n  } catch (err) {\n    if (err instanceof TypeError || err instanceof JWEInvalid || err instanceof JOSENotSupported) {\n      throw err\n    }\n    // https://www.rfc-editor.org/rfc/rfc7516#section-11.5\n    // To mitigate the attacks described in RFC 3218, the\n    // recipient MUST NOT distinguish between format, padding, and length\n    // errors of encrypted keys.  It is strongly recommended, in the event\n    // of receiving an improperly formatted key, that the recipient\n    // substitute a randomly generated CEK and proceed to the next step, to\n    // mitigate timing attacks.\n    cek = generateCek(enc)\n  }\n\n  let iv: Uint8Array | undefined\n  let tag: Uint8Array | undefined\n  if (jwe.iv !== undefined) {\n    iv = decodeBase64url(jwe.iv, 'iv', JWEInvalid)\n  }\n  if (jwe.tag !== undefined) {\n    tag = decodeBase64url(jwe.tag, 'tag', JWEInvalid)\n  }\n\n  const protectedHeader: Uint8Array =\n    jwe.protected !== undefined ? encode(jwe.protected) : new Uint8Array()\n  let additionalData: Uint8Array\n\n  if (jwe.aad !== undefined) {\n    additionalData = concat(protectedHeader, encode('.'), encode(jwe.aad))\n  } else {\n    additionalData = protectedHeader\n  }\n\n  const ciphertext = decodeBase64url(jwe.ciphertext, 'ciphertext', JWEInvalid)\n  const plaintext = await decrypt(enc, cek, ciphertext, iv, tag, additionalData)\n\n  const result: types.FlattenedDecryptResult = { plaintext }\n\n  if (joseHeader.zip === 'DEF') {\n    const maxDecompressedLength = options?.maxDecompressedLength ?? 250_000\n    if (maxDecompressedLength === 0) {\n      throw new JOSENotSupported(\n        'JWE \"zip\" (Compression Algorithm) Header Parameter is not supported.',\n      )\n    }\n    if (\n      maxDecompressedLength !== Infinity &&\n      (!Number.isSafeInteger(maxDecompressedLength) || maxDecompressedLength < 1)\n    ) {\n      throw new TypeError('maxDecompressedLength must be 0, a positive safe integer, or Infinity')\n    }\n    result.plaintext = await decompress(plaintext, maxDecompressedLength).catch((cause) => {\n      if (cause instanceof JWEInvalid) throw cause\n      throw new JWEInvalid('Failed to decompress plaintext', { cause })\n    })\n  }\n\n  if (jwe.protected !== undefined) {\n    result.protectedHeader = parsedProt\n  }\n\n  if (jwe.aad !== undefined) {\n    result.additionalAuthenticatedData = decodeBase64url(jwe.aad!, 'aad', JWEInvalid)\n  }\n\n  if (jwe.unprotected !== undefined) {\n    result.sharedUnprotectedHeader = jwe.unprotected\n  }\n\n  if (jwe.header !== undefined) {\n    result.unprotectedHeader = jwe.header\n  }\n\n  if (resolvedKey) {\n    return { ...result, key: k }\n  }\n\n  return result\n}\n"
  },
  {
    "path": "src/jwe/flattened/encrypt.ts",
    "content": "/**\n * Encrypting JSON Web Encryption (JWE) in Flattened JSON Serialization\n *\n * @module\n */\n\nimport { encode as b64u } from '../../util/base64url.js'\nimport { unprotected, assertNotSet } from '../../lib/helpers.js'\nimport { encrypt } from '../../lib/content_encryption.js'\nimport type * as types from '../../types.d.ts'\nimport { encryptKeyManagement } from '../../lib/key_management.js'\nimport { JOSENotSupported, JWEInvalid } from '../../util/errors.js'\nimport { isDisjoint } from '../../lib/type_checks.js'\nimport { concat, encode } from '../../lib/buffer_utils.js'\nimport { validateCrit } from '../../lib/validate_crit.js'\nimport { normalizeKey } from '../../lib/normalize_key.js'\nimport { checkKeyType } from '../../lib/check_key_type.js'\nimport { compress } from '../../lib/deflate.js'\n\n/**\n * The FlattenedEncrypt class is used to build and encrypt Flattened JWE objects.\n *\n * This class is exported (as a named export) from the main `'jose'` module entry point as well as\n * from its subpath export `'jose/jwe/flattened/encrypt'`.\n *\n * @example\n *\n * ```js\n * const jwe = await new jose.FlattenedEncrypt(\n *   new TextEncoder().encode('It’s a dangerous business, Frodo, going out your door.'),\n * )\n *   .setProtectedHeader({ alg: 'RSA-OAEP-256', enc: 'A256GCM' })\n *   .setAdditionalAuthenticatedData(encoder.encode('The Fellowship of the Ring'))\n *   .encrypt(publicKey)\n *\n * console.log(jwe)\n * ```\n */\nexport class FlattenedEncrypt {\n  #plaintext: Uint8Array\n\n  #protectedHeader!: types.JWEHeaderParameters | undefined\n\n  #sharedUnprotectedHeader!: types.JWEHeaderParameters | undefined\n\n  #unprotectedHeader!: types.JWEHeaderParameters | undefined\n\n  #aad!: Uint8Array | undefined\n\n  #cek!: Uint8Array | undefined\n\n  #iv!: Uint8Array | undefined\n\n  #keyManagementParameters?: types.JWEKeyManagementHeaderParameters\n\n  /**\n   * {@link FlattenedEncrypt} constructor\n   *\n   * @param plaintext Binary representation of the plaintext to encrypt.\n   */\n  constructor(plaintext: Uint8Array) {\n    if (!(plaintext instanceof Uint8Array)) {\n      throw new TypeError('plaintext must be an instance of Uint8Array')\n    }\n    this.#plaintext = plaintext\n  }\n\n  /**\n   * Sets the JWE Key Management parameters to be used when encrypting.\n   *\n   * (ECDH-ES) Use of this method is needed for ECDH based algorithms to set the \"apu\" (Agreement\n   * PartyUInfo) or \"apv\" (Agreement PartyVInfo) parameters.\n   *\n   * @param parameters JWE Key Management parameters.\n   */\n  setKeyManagementParameters(parameters: types.JWEKeyManagementHeaderParameters): this {\n    assertNotSet(this.#keyManagementParameters, 'setKeyManagementParameters')\n    this.#keyManagementParameters = parameters\n    return this\n  }\n\n  /**\n   * Sets the JWE Protected Header on the FlattenedEncrypt object.\n   *\n   * @param protectedHeader JWE Protected Header.\n   */\n  setProtectedHeader(protectedHeader: types.JWEHeaderParameters): this {\n    assertNotSet(this.#protectedHeader, 'setProtectedHeader')\n    this.#protectedHeader = protectedHeader\n    return this\n  }\n\n  /**\n   * Sets the JWE Shared Unprotected Header on the FlattenedEncrypt object.\n   *\n   * @param sharedUnprotectedHeader JWE Shared Unprotected Header.\n   */\n  setSharedUnprotectedHeader(sharedUnprotectedHeader: types.JWEHeaderParameters): this {\n    assertNotSet(this.#sharedUnprotectedHeader, 'setSharedUnprotectedHeader')\n    this.#sharedUnprotectedHeader = sharedUnprotectedHeader\n    return this\n  }\n\n  /**\n   * Sets the JWE Per-Recipient Unprotected Header on the FlattenedEncrypt object.\n   *\n   * @param unprotectedHeader JWE Per-Recipient Unprotected Header.\n   */\n  setUnprotectedHeader(unprotectedHeader: types.JWEHeaderParameters): this {\n    assertNotSet(this.#unprotectedHeader, 'setUnprotectedHeader')\n    this.#unprotectedHeader = unprotectedHeader\n    return this\n  }\n\n  /**\n   * Sets the Additional Authenticated Data on the FlattenedEncrypt object.\n   *\n   * @param aad Additional Authenticated Data.\n   */\n  setAdditionalAuthenticatedData(aad: Uint8Array): this {\n    this.#aad = aad\n    return this\n  }\n\n  /**\n   * Sets a content encryption key to use, by default a random suitable one is generated for the JWE\n   * enc\" (Encryption Algorithm) Header Parameter.\n   *\n   * @deprecated You should not use this method. It is only really intended for test and vector\n   *   validation purposes.\n   *\n   * @param cek JWE Content Encryption Key.\n   */\n  setContentEncryptionKey(cek: Uint8Array): this {\n    assertNotSet(this.#cek, 'setContentEncryptionKey')\n    this.#cek = cek\n    return this\n  }\n\n  /**\n   * Sets the JWE Initialization Vector to use for content encryption, by default a random suitable\n   * one is generated for the JWE enc\" (Encryption Algorithm) Header Parameter.\n   *\n   * @deprecated You should not use this method. It is only really intended for test and vector\n   *   validation purposes.\n   *\n   * @param iv JWE Initialization Vector.\n   */\n  setInitializationVector(iv: Uint8Array): this {\n    assertNotSet(this.#iv, 'setInitializationVector')\n    this.#iv = iv\n    return this\n  }\n\n  /**\n   * Encrypts and resolves the value of the Flattened JWE object.\n   *\n   * @param key Public Key or Secret to encrypt the JWE with. See\n   *   {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}.\n   * @param options JWE Encryption options.\n   */\n  async encrypt(\n    key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n    options?: types.EncryptOptions,\n  ): Promise<types.FlattenedJWE> {\n    if (!this.#protectedHeader && !this.#unprotectedHeader && !this.#sharedUnprotectedHeader) {\n      throw new JWEInvalid(\n        'either setProtectedHeader, setUnprotectedHeader, or sharedUnprotectedHeader must be called before #encrypt()',\n      )\n    }\n\n    if (\n      !isDisjoint(this.#protectedHeader, this.#unprotectedHeader, this.#sharedUnprotectedHeader)\n    ) {\n      throw new JWEInvalid(\n        'JWE Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint',\n      )\n    }\n\n    const joseHeader: types.JWEHeaderParameters = {\n      ...this.#protectedHeader,\n      ...this.#unprotectedHeader,\n      ...this.#sharedUnprotectedHeader,\n    }\n\n    validateCrit(JWEInvalid, new Map(), options?.crit, this.#protectedHeader, joseHeader)\n\n    if (joseHeader.zip !== undefined && joseHeader.zip !== 'DEF') {\n      throw new JOSENotSupported(\n        'Unsupported JWE \"zip\" (Compression Algorithm) Header Parameter value.',\n      )\n    }\n\n    if (joseHeader.zip !== undefined && !this.#protectedHeader?.zip) {\n      throw new JWEInvalid(\n        'JWE \"zip\" (Compression Algorithm) Header Parameter MUST be in a protected header.',\n      )\n    }\n\n    const { alg, enc } = joseHeader\n\n    if (typeof alg !== 'string' || !alg) {\n      throw new JWEInvalid('JWE \"alg\" (Algorithm) Header Parameter missing or invalid')\n    }\n\n    if (typeof enc !== 'string' || !enc) {\n      throw new JWEInvalid('JWE \"enc\" (Encryption Algorithm) Header Parameter missing or invalid')\n    }\n\n    let encryptedKey: Uint8Array | undefined\n\n    if (this.#cek && (alg === 'dir' || alg === 'ECDH-ES')) {\n      throw new TypeError(\n        `setContentEncryptionKey cannot be called with JWE \"alg\" (Algorithm) Header ${alg}`,\n      )\n    }\n\n    checkKeyType(alg === 'dir' ? enc : alg, key, 'encrypt')\n\n    let cek: types.CryptoKey | Uint8Array\n    {\n      let parameters: { [propName: string]: unknown } | undefined\n      const k = await normalizeKey(key, alg)\n      ;({ cek, encryptedKey, parameters } = await encryptKeyManagement(\n        alg,\n        enc,\n        k,\n        this.#cek,\n        this.#keyManagementParameters,\n      ))\n\n      if (parameters) {\n        if (options && unprotected in options) {\n          if (!this.#unprotectedHeader) {\n            this.setUnprotectedHeader(parameters)\n          } else {\n            this.#unprotectedHeader = { ...this.#unprotectedHeader, ...parameters }\n          }\n        } else if (!this.#protectedHeader) {\n          this.setProtectedHeader(parameters)\n        } else {\n          this.#protectedHeader = { ...this.#protectedHeader, ...parameters }\n        }\n      }\n    }\n\n    let additionalData: Uint8Array\n    let protectedHeaderS: string\n    let protectedHeaderB: Uint8Array\n    let aadMember: string | undefined\n    if (this.#protectedHeader) {\n      protectedHeaderS = b64u(JSON.stringify(this.#protectedHeader))\n      protectedHeaderB = encode(protectedHeaderS)\n    } else {\n      protectedHeaderS = ''\n      protectedHeaderB = new Uint8Array()\n    }\n\n    if (this.#aad) {\n      aadMember = b64u(this.#aad)\n      const aadMemberBytes = encode(aadMember)\n      additionalData = concat(protectedHeaderB, encode('.'), aadMemberBytes)\n    } else {\n      additionalData = protectedHeaderB\n    }\n\n    let plaintext = this.#plaintext\n    if (joseHeader.zip === 'DEF') {\n      plaintext = await compress(plaintext).catch((cause) => {\n        throw new JWEInvalid('Failed to compress plaintext', { cause })\n      })\n    }\n\n    const { ciphertext, tag, iv } = await encrypt(enc, plaintext, cek, this.#iv, additionalData)\n\n    const jwe: types.FlattenedJWE = {\n      ciphertext: b64u(ciphertext),\n    }\n\n    if (iv) {\n      jwe.iv = b64u(iv)\n    }\n\n    if (tag) {\n      jwe.tag = b64u(tag)\n    }\n\n    if (encryptedKey) {\n      jwe.encrypted_key = b64u(encryptedKey)\n    }\n\n    if (aadMember) {\n      jwe.aad = aadMember\n    }\n\n    if (this.#protectedHeader) {\n      jwe.protected = protectedHeaderS\n    }\n\n    if (this.#sharedUnprotectedHeader) {\n      jwe.unprotected = this.#sharedUnprotectedHeader\n    }\n\n    if (this.#unprotectedHeader) {\n      jwe.header = this.#unprotectedHeader\n    }\n\n    return jwe\n  }\n}\n"
  },
  {
    "path": "src/jwe/general/decrypt.ts",
    "content": "/**\n * Decrypting JSON Web Encryption (JWE) in General JSON Serialization\n *\n * @module\n */\n\nimport { flattenedDecrypt } from '../flattened/decrypt.js'\nimport { JWEDecryptionFailed, JWEInvalid } from '../../util/errors.js'\nimport type * as types from '../../types.d.ts'\nimport { isObject } from '../../lib/type_checks.js'\n\n/**\n * Interface for General JWE Decryption dynamic key resolution. No token components have been\n * verified at the time of this function call.\n */\nexport interface GeneralDecryptGetKey extends types.GetKeyFunction<\n  types.JWEHeaderParameters,\n  types.FlattenedJWE\n> {}\n\n/**\n * Decrypts a General JWE.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/jwe/general/decrypt'`.\n *\n * > [!NOTE]\\\n * > The function iterates over the `recipients` array in the General JWE and returns the decryption\n * > result of the first recipient entry that can be successfully decrypted. The result only contains\n * > the plaintext and headers of that successfully decrypted recipient entry. Other recipient entries\n * > in the General JWE are not validated, and their headers are not included in the returned result.\n * > Recipients of a General JWE should only rely on the returned (decrypted) data.\n *\n * @example\n *\n * ```js\n * const jwe = {\n *   ciphertext: '9EzjFISUyoG-ifC2mSihfP0DPC80yeyrxhTzKt1C_VJBkxeBG0MI4Te61Pk45RAGubUvBpU9jm4',\n *   iv: '8Fy7A_IuoX5VXG9s',\n *   tag: 'W76IYV6arGRuDSaSyWrQNg',\n *   aad: 'VGhlIEZlbGxvd3NoaXAgb2YgdGhlIFJpbmc',\n *   protected: 'eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0',\n *   recipients: [\n *     {\n *       encrypted_key:\n *         'Z6eD4UK_yFb5ZoKvKkGAdqywEG_m0e4IYo0x8Vf30LAMJcsc-_zSgIeiF82teZyYi2YYduHKoqImk7MRnoPZOlEs0Q5BNK1OgBmSOhCE8DFyqh9Zh48TCTP6lmBQ52naqoUJFMtHzu-0LwZH26hxos0GP3Dt19O379MJB837TdKKa87skq0zHaVLAquRHOBF77GI54Bc7O49d8aOrSu1VEFGMThlW2caspPRiTSePDMDPq7_WGk50izRhB3Asl9wmP9wEeaTrkJKRnQj5ips1SAZ1hDBsqEQKKukxP1HtdcopHV5_qgwU8Hjm5EwSLMluMQuiE6hwlkXGOujZLVizA',\n *     },\n *   ],\n * }\n *\n * const { plaintext, protectedHeader, additionalAuthenticatedData } =\n *   await jose.generalDecrypt(jwe, privateKey)\n *\n * console.log(protectedHeader)\n * const decoder = new TextDecoder()\n * console.log(decoder.decode(plaintext))\n * console.log(decoder.decode(additionalAuthenticatedData))\n * ```\n *\n * @param jwe General JWE.\n * @param key Private Key or Secret to decrypt the JWE with. See\n *   {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}.\n * @param options JWE Decryption options.\n */\nexport function generalDecrypt(\n  jwe: types.GeneralJWE,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n  options?: types.DecryptOptions,\n): Promise<types.GeneralDecryptResult>\n/**\n * @param jwe General JWE.\n * @param getKey Function resolving Private Key or Secret to decrypt the JWE with. See\n *   {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}.\n * @param options JWE Decryption options.\n */\nexport function generalDecrypt(\n  jwe: types.GeneralJWE,\n  getKey: GeneralDecryptGetKey,\n  options?: types.DecryptOptions,\n): Promise<types.GeneralDecryptResult & types.ResolvedKey>\nexport async function generalDecrypt(\n  jwe: types.GeneralJWE,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array | GeneralDecryptGetKey,\n  options?: types.DecryptOptions,\n) {\n  if (!isObject(jwe)) {\n    throw new JWEInvalid('General JWE must be an object')\n  }\n\n  if (!Array.isArray(jwe.recipients) || !jwe.recipients.every(isObject)) {\n    throw new JWEInvalid('JWE Recipients missing or incorrect type')\n  }\n\n  if (!jwe.recipients.length) {\n    throw new JWEInvalid('JWE Recipients has no members')\n  }\n\n  for (const recipient of jwe.recipients) {\n    try {\n      return await flattenedDecrypt(\n        {\n          aad: jwe.aad,\n          ciphertext: jwe.ciphertext,\n          encrypted_key: recipient.encrypted_key,\n          header: recipient.header,\n          iv: jwe.iv,\n          protected: jwe.protected,\n          tag: jwe.tag,\n          unprotected: jwe.unprotected,\n        },\n        key as Parameters<typeof flattenedDecrypt>[1],\n        options,\n      )\n    } catch {\n      //\n    }\n  }\n  throw new JWEDecryptionFailed()\n}\n"
  },
  {
    "path": "src/jwe/general/encrypt.ts",
    "content": "/**\n * Encrypting JSON Web Encryption (JWE) in General JSON Serialization\n *\n * @module\n */\n\nimport type * as types from '../../types.d.ts'\nimport { FlattenedEncrypt } from '../flattened/encrypt.js'\nimport { unprotected, assertNotSet } from '../../lib/helpers.js'\nimport { JOSENotSupported, JWEInvalid } from '../../util/errors.js'\nimport { generateCek } from '../../lib/content_encryption.js'\nimport { isDisjoint } from '../../lib/type_checks.js'\nimport { encryptKeyManagement } from '../../lib/key_management.js'\nimport { encode as b64u } from '../../util/base64url.js'\nimport { validateCrit } from '../../lib/validate_crit.js'\nimport { normalizeKey } from '../../lib/normalize_key.js'\nimport { checkKeyType } from '../../lib/check_key_type.js'\n\n/** Used to build General JWE object's individual recipients. */\nexport interface Recipient {\n  /**\n   * Sets the JWE Per-Recipient Unprotected Header on the Recipient object.\n   *\n   * @param unprotectedHeader JWE Per-Recipient Unprotected Header.\n   */\n  setUnprotectedHeader(unprotectedHeader: types.JWEHeaderParameters): Recipient\n\n  /**\n   * Sets the JWE Key Management parameters to be used when encrypting.\n   *\n   * (ECDH-ES) Use of this method is needed for ECDH based algorithms to set the \"apu\" (Agreement\n   * PartyUInfo) or \"apv\" (Agreement PartyVInfo) parameters.\n   *\n   * @param parameters JWE Key Management parameters.\n   */\n  setKeyManagementParameters(parameters: types.JWEKeyManagementHeaderParameters): Recipient\n\n  /** A shorthand for calling addRecipient() on the enclosing {@link GeneralEncrypt} instance */\n  addRecipient(...args: Parameters<GeneralEncrypt['addRecipient']>): Recipient\n\n  /** A shorthand for calling encrypt() on the enclosing {@link GeneralEncrypt} instance */\n  encrypt(...args: Parameters<GeneralEncrypt['encrypt']>): Promise<types.GeneralJWE>\n\n  /** Returns the enclosing {@link GeneralEncrypt} instance */\n  done(): GeneralEncrypt\n}\n\nclass IndividualRecipient implements Recipient {\n  #parent: GeneralEncrypt\n  unprotectedHeader?: types.JWEHeaderParameters\n  keyManagementParameters?: types.JWEKeyManagementHeaderParameters\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array\n  options: types.CritOption\n\n  constructor(\n    enc: GeneralEncrypt,\n    key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n    options: types.CritOption,\n  ) {\n    this.#parent = enc\n    this.key = key\n    this.options = options\n  }\n\n  setUnprotectedHeader(unprotectedHeader: types.JWEHeaderParameters): this {\n    assertNotSet(this.unprotectedHeader, 'setUnprotectedHeader')\n    this.unprotectedHeader = unprotectedHeader\n    return this\n  }\n\n  setKeyManagementParameters(parameters: types.JWEKeyManagementHeaderParameters): this {\n    assertNotSet(this.keyManagementParameters, 'setKeyManagementParameters')\n    this.keyManagementParameters = parameters\n    return this\n  }\n\n  addRecipient(...args: Parameters<GeneralEncrypt['addRecipient']>) {\n    return this.#parent.addRecipient(...args)\n  }\n\n  encrypt(...args: Parameters<GeneralEncrypt['encrypt']>) {\n    return this.#parent.encrypt(...args)\n  }\n\n  done() {\n    return this.#parent\n  }\n}\n\n/**\n * The GeneralEncrypt class is used to build and encrypt General JWE objects.\n *\n * This class is exported (as a named export) from the main `'jose'` module entry point as well as\n * from its subpath export `'jose/jwe/general/encrypt'`.\n *\n * @example\n *\n * ```js\n * const jwe = await new jose.GeneralEncrypt(\n *   new TextEncoder().encode('It’s a dangerous business, Frodo, going out your door.'),\n * )\n *   .setProtectedHeader({ enc: 'A256GCM' })\n *   .addRecipient(ecPublicKey)\n *   .setUnprotectedHeader({ alg: 'ECDH-ES+A256KW' })\n *   .addRecipient(rsaPublicKey)\n *   .setUnprotectedHeader({ alg: 'RSA-OAEP-384' })\n *   .encrypt()\n *\n * console.log(jwe)\n * ```\n */\nexport class GeneralEncrypt {\n  #plaintext: Uint8Array\n\n  #recipients: IndividualRecipient[] = []\n\n  #protectedHeader!: types.JWEHeaderParameters\n\n  #unprotectedHeader!: types.JWEHeaderParameters\n\n  #aad!: Uint8Array\n\n  /**\n   * {@link GeneralEncrypt} constructor\n   *\n   * @param plaintext Binary representation of the plaintext to encrypt.\n   */\n  constructor(plaintext: Uint8Array) {\n    this.#plaintext = plaintext\n  }\n\n  /**\n   * Adds an additional recipient for the General JWE object.\n   *\n   * @param key Public Key or Secret to encrypt the Content Encryption Key for the recipient with.\n   *   See {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}.\n   * @param options JWE Encryption options.\n   */\n  addRecipient(\n    key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n    options?: types.CritOption,\n  ): Recipient {\n    const recipient = new IndividualRecipient(this, key, { crit: options?.crit })\n    this.#recipients.push(recipient)\n    return recipient\n  }\n\n  /**\n   * Sets the JWE Protected Header on the GeneralEncrypt object.\n   *\n   * @param protectedHeader JWE Protected Header object.\n   */\n  setProtectedHeader(protectedHeader: types.JWEHeaderParameters): this {\n    assertNotSet(this.#protectedHeader, 'setProtectedHeader')\n    this.#protectedHeader = protectedHeader\n    return this\n  }\n\n  /**\n   * Sets the JWE Shared Unprotected Header on the GeneralEncrypt object.\n   *\n   * @param sharedUnprotectedHeader JWE Shared Unprotected Header object.\n   */\n  setSharedUnprotectedHeader(sharedUnprotectedHeader: types.JWEHeaderParameters): this {\n    assertNotSet(this.#unprotectedHeader, 'setSharedUnprotectedHeader')\n    this.#unprotectedHeader = sharedUnprotectedHeader\n    return this\n  }\n\n  /**\n   * Sets the Additional Authenticated Data on the GeneralEncrypt object.\n   *\n   * @param aad Additional Authenticated Data.\n   */\n  setAdditionalAuthenticatedData(aad: Uint8Array): this {\n    this.#aad = aad\n    return this\n  }\n\n  /** Encrypts and resolves the value of the General JWE object. */\n  async encrypt(): Promise<types.GeneralJWE> {\n    if (!this.#recipients.length) {\n      throw new JWEInvalid('at least one recipient must be added')\n    }\n\n    if (this.#recipients.length === 1) {\n      const [recipient] = this.#recipients\n\n      const flattened = await new FlattenedEncrypt(this.#plaintext)\n        .setAdditionalAuthenticatedData(this.#aad)\n        .setProtectedHeader(this.#protectedHeader)\n        .setSharedUnprotectedHeader(this.#unprotectedHeader)\n        .setUnprotectedHeader(recipient.unprotectedHeader!)\n        .encrypt(recipient.key, { ...recipient.options })\n\n      const jwe: types.GeneralJWE = {\n        ciphertext: flattened.ciphertext,\n        iv: flattened.iv,\n        recipients: [{}],\n        tag: flattened.tag,\n      }\n\n      if (flattened.aad) jwe.aad = flattened.aad\n      if (flattened.protected) jwe.protected = flattened.protected\n      if (flattened.unprotected) jwe.unprotected = flattened.unprotected\n      if (flattened.encrypted_key) jwe.recipients![0].encrypted_key = flattened.encrypted_key\n      if (flattened.header) jwe.recipients![0].header = flattened.header\n\n      return jwe\n    }\n\n    let enc!: string\n    for (let i = 0; i < this.#recipients.length; i++) {\n      const recipient = this.#recipients[i]\n      if (\n        !isDisjoint(this.#protectedHeader, this.#unprotectedHeader, recipient.unprotectedHeader)\n      ) {\n        throw new JWEInvalid(\n          'JWE Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint',\n        )\n      }\n\n      const joseHeader = {\n        ...this.#protectedHeader,\n        ...this.#unprotectedHeader,\n        ...recipient.unprotectedHeader,\n      }\n\n      const { alg } = joseHeader\n\n      if (typeof alg !== 'string' || !alg) {\n        throw new JWEInvalid('JWE \"alg\" (Algorithm) Header Parameter missing or invalid')\n      }\n\n      if (alg === 'dir' || alg === 'ECDH-ES') {\n        throw new JWEInvalid('\"dir\" and \"ECDH-ES\" alg may only be used with a single recipient')\n      }\n\n      if (typeof joseHeader.enc !== 'string' || !joseHeader.enc) {\n        throw new JWEInvalid('JWE \"enc\" (Encryption Algorithm) Header Parameter missing or invalid')\n      }\n\n      if (!enc) {\n        enc = joseHeader.enc\n      } else if (enc !== joseHeader.enc) {\n        throw new JWEInvalid(\n          'JWE \"enc\" (Encryption Algorithm) Header Parameter must be the same for all recipients',\n        )\n      }\n\n      validateCrit(JWEInvalid, new Map(), recipient.options.crit, this.#protectedHeader, joseHeader)\n\n      if (joseHeader.zip !== undefined && joseHeader.zip !== 'DEF') {\n        throw new JOSENotSupported(\n          'Unsupported JWE \"zip\" (Compression Algorithm) Header Parameter value.',\n        )\n      }\n\n      if (joseHeader.zip !== undefined && !this.#protectedHeader?.zip) {\n        throw new JWEInvalid(\n          'JWE \"zip\" (Compression Algorithm) Header Parameter MUST be in a protected header.',\n        )\n      }\n    }\n\n    const cek = generateCek(enc)\n\n    const jwe: types.GeneralJWE = {\n      ciphertext: '',\n      recipients: [],\n    }\n\n    for (let i = 0; i < this.#recipients.length; i++) {\n      const recipient = this.#recipients[i]\n      const target: Record<string, string | types.JWEHeaderParameters> = {}\n      jwe.recipients!.push(target)\n\n      if (i === 0) {\n        const flattened = await new FlattenedEncrypt(this.#plaintext)\n          .setAdditionalAuthenticatedData(this.#aad)\n          .setContentEncryptionKey(cek)\n          .setProtectedHeader(this.#protectedHeader)\n          .setSharedUnprotectedHeader(this.#unprotectedHeader)\n          .setUnprotectedHeader(recipient.unprotectedHeader!)\n          .setKeyManagementParameters(recipient.keyManagementParameters!)\n          .encrypt(recipient.key, {\n            ...recipient.options,\n            // @ts-expect-error\n            [unprotected]: true,\n          })\n\n        jwe.ciphertext = flattened.ciphertext\n        jwe.iv = flattened.iv\n        jwe.tag = flattened.tag\n\n        if (flattened.aad) jwe.aad = flattened.aad\n        if (flattened.protected) jwe.protected = flattened.protected\n        if (flattened.unprotected) jwe.unprotected = flattened.unprotected\n\n        target.encrypted_key = flattened.encrypted_key!\n        if (flattened.header) target.header = flattened.header\n\n        continue\n      }\n\n      const alg =\n        recipient.unprotectedHeader?.alg! ||\n        this.#protectedHeader?.alg! ||\n        this.#unprotectedHeader?.alg!\n\n      checkKeyType(alg === 'dir' ? enc : alg, recipient.key, 'encrypt')\n\n      const k = await normalizeKey(recipient.key, alg)\n      const { encryptedKey, parameters } = await encryptKeyManagement(\n        alg,\n        enc,\n        k,\n        cek,\n        recipient.keyManagementParameters,\n      )\n      target.encrypted_key = b64u(encryptedKey!)\n      if (recipient.unprotectedHeader || parameters)\n        target.header = { ...recipient.unprotectedHeader, ...parameters }\n    }\n\n    return jwe as types.GeneralJWE\n  }\n}\n"
  },
  {
    "path": "src/jwk/embedded.ts",
    "content": "/**\n * Verification using a JWK Embedded in a JWS Header\n *\n * @module\n */\n\nimport type * as types from '../types.d.ts'\nimport { importJWK } from '../key/import.js'\nimport { isObject } from '../lib/type_checks.js'\nimport { JWSInvalid } from '../util/errors.js'\n\n/**\n * EmbeddedJWK is an implementation of a GetKeyFunction intended to be used with the JWS/JWT verify\n * operations whenever you need to opt-in to verify signatures with a public key embedded in the\n * token's \"jwk\" (JSON Web Key) Header Parameter. It is recommended to combine this with the verify\n * function's `algorithms` option to define accepted JWS \"alg\" (Algorithm) Header Parameter values.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/jwk/embedded'`.\n *\n * @example\n *\n * ```js\n * const jwt =\n *   'eyJqd2siOnsiY3J2IjoiUC0yNTYiLCJ4IjoiVU05ZzVuS25aWFlvdldBbE03NmNMejl2VG96UmpfX0NIVV9kT2wtZ09vRSIsInkiOiJkczhhZVF3MWwyY0RDQTdiQ2tPTnZ3REtwWEFidFhqdnFDbGVZSDhXc19VIiwia3R5IjoiRUMifSwiYWxnIjoiRVMyNTYifQ.eyJpc3MiOiJ1cm46ZXhhbXBsZTppc3N1ZXIiLCJhdWQiOiJ1cm46ZXhhbXBsZTphdWRpZW5jZSIsImlhdCI6MTYwNDU4MDc5NH0.60boak3_dErnW47ZPty1C0nrjeVq86EN_eK0GOq6K8w2OA0thKoBxFK4j-NuU9yZ_A9UKGxPT_G87DladBaV9g'\n *\n * const { payload, protectedHeader } = await jose.jwtVerify(jwt, jose.EmbeddedJWK, {\n *   issuer: 'urn:example:issuer',\n *   audience: 'urn:example:audience',\n * })\n *\n * console.log(protectedHeader)\n * console.log(payload)\n * ```\n */\nexport async function EmbeddedJWK(\n  protectedHeader?: types.JWSHeaderParameters,\n  token?: types.FlattenedJWSInput,\n): Promise<types.CryptoKey> {\n  const joseHeader = {\n    ...protectedHeader,\n    ...token?.header,\n  }\n  if (!isObject(joseHeader.jwk)) {\n    throw new JWSInvalid('\"jwk\" (JSON Web Key) Header Parameter must be a JSON object')\n  }\n\n  const key = await importJWK({ ...joseHeader.jwk, ext: true }, joseHeader.alg!)\n\n  if (key instanceof Uint8Array || key.type !== 'public') {\n    throw new JWSInvalid('\"jwk\" (JSON Web Key) Header Parameter must be a public key')\n  }\n\n  return key\n}\n"
  },
  {
    "path": "src/jwk/thumbprint.ts",
    "content": "/**\n * JSON Web Key Thumbprint and JSON Web Key Thumbprint URI\n *\n * @module\n */\n\nimport { digest } from '../lib/helpers.js'\nimport { encode as b64u } from '../util/base64url.js'\n\nimport { JOSENotSupported, JWKInvalid } from '../util/errors.js'\nimport { encode } from '../lib/buffer_utils.js'\nimport type * as types from '../types.d.ts'\nimport { isKeyLike } from '../lib/is_key_like.js'\nimport { isJWK } from '../lib/type_checks.js'\nimport { exportJWK } from '../key/export.js'\nimport { invalidKeyInput } from '../lib/invalid_key_input.js'\n\nconst check = (value: unknown, description: string) => {\n  if (typeof value !== 'string' || !value) {\n    throw new JWKInvalid(`${description} missing or invalid`)\n  }\n}\n\n/**\n * Calculates a base64url-encoded JSON Web Key (JWK) Thumbprint\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/jwk/thumbprint'`.\n *\n * @example\n *\n * ```js\n * const thumbprint = await jose.calculateJwkThumbprint({\n *   kty: 'EC',\n *   crv: 'P-256',\n *   x: 'jJ6Flys3zK9jUhnOHf6G49Dyp5hah6CNP84-gY-n9eo',\n *   y: 'nhI6iD5eFXgBTLt_1p3aip-5VbZeMhxeFSpjfEAf7Ww',\n * })\n *\n * console.log(thumbprint)\n * // 'w9eYdC6_s_tLQ8lH6PUpc0mddazaqtPgeC2IgWDiqY8'\n * ```\n *\n * @param key Key to calculate the thumbprint for.\n * @param digestAlgorithm Digest Algorithm to use for calculating the thumbprint. Default is\n *   \"sha256\".\n *\n * @see {@link https://www.rfc-editor.org/rfc/rfc7638 RFC7638}\n */\nexport async function calculateJwkThumbprint(\n  key: types.JWK | types.CryptoKey | types.KeyObject,\n  digestAlgorithm?: 'sha256' | 'sha384' | 'sha512',\n): Promise<string> {\n  let jwk: types.JWK\n  if (isJWK(key)) {\n    jwk = key\n  } else if (isKeyLike(key)) {\n    jwk = await exportJWK(key)\n  } else {\n    throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'KeyObject', 'JSON Web Key'))\n  }\n\n  digestAlgorithm ??= 'sha256'\n\n  if (\n    digestAlgorithm !== 'sha256' &&\n    digestAlgorithm !== 'sha384' &&\n    digestAlgorithm !== 'sha512'\n  ) {\n    throw new TypeError('digestAlgorithm must one of \"sha256\", \"sha384\", or \"sha512\"')\n  }\n\n  let components: types.JWK\n  switch (jwk.kty) {\n    case 'AKP':\n      check(jwk.alg, '\"alg\" (Algorithm) Parameter')\n      check(jwk.pub, '\"pub\" (Public key) Parameter')\n      components = { alg: jwk.alg, kty: jwk.kty, pub: jwk.pub }\n      break\n    case 'EC':\n      check(jwk.crv, '\"crv\" (Curve) Parameter')\n      check(jwk.x, '\"x\" (X Coordinate) Parameter')\n      check(jwk.y, '\"y\" (Y Coordinate) Parameter')\n      components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y }\n      break\n    case 'OKP':\n      check(jwk.crv, '\"crv\" (Subtype of Key Pair) Parameter')\n      check(jwk.x, '\"x\" (Public Key) Parameter')\n      components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x }\n      break\n    case 'RSA':\n      check(jwk.e, '\"e\" (Exponent) Parameter')\n      check(jwk.n, '\"n\" (Modulus) Parameter')\n      components = { e: jwk.e, kty: jwk.kty, n: jwk.n }\n      break\n    case 'oct':\n      check(jwk.k, '\"k\" (Key Value) Parameter')\n      components = { k: jwk.k, kty: jwk.kty }\n      break\n    default:\n      throw new JOSENotSupported('\"kty\" (Key Type) Parameter missing or unsupported')\n  }\n\n  const data = encode(JSON.stringify(components))\n  return b64u(await digest(digestAlgorithm, data))\n}\n\n/**\n * Calculates a JSON Web Key (JWK) Thumbprint URI\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/jwk/thumbprint'`.\n *\n * @example\n *\n * ```js\n * const thumbprintUri = await jose.calculateJwkThumbprintUri({\n *   kty: 'EC',\n *   crv: 'P-256',\n *   x: 'jJ6Flys3zK9jUhnOHf6G49Dyp5hah6CNP84-gY-n9eo',\n *   y: 'nhI6iD5eFXgBTLt_1p3aip-5VbZeMhxeFSpjfEAf7Ww',\n * })\n *\n * console.log(thumbprintUri)\n * // 'urn:ietf:params:oauth:jwk-thumbprint:sha-256:w9eYdC6_s_tLQ8lH6PUpc0mddazaqtPgeC2IgWDiqY8'\n * ```\n *\n * @param key Key to calculate the thumbprint for.\n * @param digestAlgorithm Digest Algorithm to use for calculating the thumbprint. Default is\n *   \"sha256\".\n *\n * @see {@link https://www.rfc-editor.org/rfc/rfc9278 RFC9278}\n */\nexport async function calculateJwkThumbprintUri(\n  key: types.CryptoKey | types.KeyObject | types.JWK,\n  digestAlgorithm?: 'sha256' | 'sha384' | 'sha512',\n): Promise<string> {\n  digestAlgorithm ??= 'sha256'\n  const thumbprint = await calculateJwkThumbprint(key, digestAlgorithm)\n  return `urn:ietf:params:oauth:jwk-thumbprint:sha-${digestAlgorithm.slice(-3)}:${thumbprint}`\n}\n"
  },
  {
    "path": "src/jwks/local.ts",
    "content": "/**\n * Verification using a JSON Web Key Set (JWKS) available locally\n *\n * @module\n */\n\nimport type * as types from '../types.d.ts'\nimport { importJWK } from '../key/import.js'\nimport {\n  JWKSInvalid,\n  JOSENotSupported,\n  JWKSNoMatchingKey,\n  JWKSMultipleMatchingKeys,\n} from '../util/errors.js'\nimport { isObject } from '../lib/type_checks.js'\n\nfunction getKtyFromAlg(alg: unknown) {\n  switch (typeof alg === 'string' && alg.slice(0, 2)) {\n    case 'RS':\n    case 'PS':\n      return 'RSA'\n    case 'ES':\n      return 'EC'\n    case 'Ed':\n      return 'OKP'\n    case 'ML':\n      return 'AKP'\n    default:\n      throw new JOSENotSupported('Unsupported \"alg\" value for a JSON Web Key Set')\n  }\n}\n\ninterface Cache {\n  [alg: string]: types.CryptoKey\n}\n\nfunction isJWKSLike(jwks: unknown): jwks is types.JSONWebKeySet {\n  return (\n    jwks &&\n    typeof jwks === 'object' &&\n    // @ts-expect-error\n    Array.isArray(jwks.keys) &&\n    // @ts-expect-error\n    jwks.keys.every(isJWKLike)\n  )\n}\n\nfunction isJWKLike(key: unknown) {\n  return isObject<types.JWK>(key)\n}\n\nclass LocalJWKSet {\n  #jwks: types.JSONWebKeySet\n\n  #cached: WeakMap<types.JWK, Cache> = new WeakMap()\n\n  constructor(jwks: unknown) {\n    if (!isJWKSLike(jwks)) {\n      throw new JWKSInvalid('JSON Web Key Set malformed')\n    }\n\n    this.#jwks = structuredClone<types.JSONWebKeySet>(jwks)\n  }\n\n  jwks(): types.JSONWebKeySet {\n    return this.#jwks\n  }\n\n  async getKey(\n    protectedHeader?: types.JWSHeaderParameters,\n    token?: types.FlattenedJWSInput,\n  ): Promise<types.CryptoKey> {\n    const { alg, kid } = { ...protectedHeader, ...token?.header }\n    const kty = getKtyFromAlg(alg)\n\n    const candidates = this.#jwks!.keys.filter((jwk) => {\n      // filter keys based on the mapping of signature algorithms to Key Type\n      let candidate = kty === jwk.kty\n\n      // filter keys based on the JWK Key ID in the header\n      if (candidate && typeof kid === 'string') {\n        candidate = kid === jwk.kid\n      }\n\n      // filter keys based on the key's declared Algorithm\n      if (candidate && (typeof jwk.alg === 'string' || kty === 'AKP')) {\n        candidate = alg === jwk.alg\n      }\n\n      // filter keys based on the key's declared Public Key Use\n      if (candidate && typeof jwk.use === 'string') {\n        candidate = jwk.use === 'sig'\n      }\n\n      // filter keys based on the key's declared Key Operations\n      if (candidate && Array.isArray(jwk.key_ops)) {\n        candidate = jwk.key_ops.includes('verify')\n      }\n\n      // filter out non-applicable curves / sub types\n      if (candidate) {\n        switch (alg) {\n          case 'ES256':\n            candidate = jwk.crv === 'P-256'\n            break\n          case 'ES384':\n            candidate = jwk.crv === 'P-384'\n            break\n          case 'ES512':\n            candidate = jwk.crv === 'P-521'\n            break\n          case 'Ed25519': // Fall through\n          case 'EdDSA':\n            candidate = jwk.crv === 'Ed25519'\n            break\n        }\n      }\n\n      return candidate\n    })\n\n    const { 0: jwk, length } = candidates\n\n    if (length === 0) {\n      throw new JWKSNoMatchingKey()\n    }\n    if (length !== 1) {\n      const error = new JWKSMultipleMatchingKeys()\n\n      const _cached = this.#cached\n      error[Symbol.asyncIterator] = async function* () {\n        for (const jwk of candidates) {\n          try {\n            yield await importWithAlgCache(_cached, jwk, alg!)\n          } catch {}\n        }\n      }\n\n      throw error\n    }\n\n    return importWithAlgCache(this.#cached, jwk, alg!)\n  }\n}\n\nasync function importWithAlgCache(cache: WeakMap<types.JWK, Cache>, jwk: types.JWK, alg: string) {\n  const cached = cache.get(jwk) || cache.set(jwk, {}).get(jwk)!\n  if (cached[alg] === undefined) {\n    const key = await importJWK({ ...jwk, ext: true }, alg)\n\n    if (key instanceof Uint8Array || key.type !== 'public') {\n      throw new JWKSInvalid('JSON Web Key Set members must be public keys')\n    }\n\n    cached[alg] = key\n  }\n\n  return cached[alg]\n}\n\n/**\n * Returns a function that resolves a JWS JOSE Header to a public key object from a locally stored,\n * or otherwise available, JSON Web Key Set.\n *\n * It uses the \"alg\" (JWS Algorithm) Header Parameter to determine the right JWK \"kty\" (Key Type),\n * then proceeds to match the JWK \"kid\" (Key ID) with one found in the JWS Header Parameters (if\n * there is one) while also respecting the JWK \"use\" (Public Key Use) and JWK \"key_ops\" (Key\n * Operations) Parameters (if they are present on the JWK).\n *\n * Only a single public key must match the selection process. As shown in the example below when\n * multiple keys get matched it is possible to opt-in to iterate over the matched keys and attempt\n * verification in an iterative manner.\n *\n * > [!NOTE]\\\n * > The function's purpose is to resolve public keys used for verifying signatures and will not work\n * > for public encryption keys.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/jwks/local'`.\n *\n * @example\n *\n * ```js\n * const JWKS = jose.createLocalJWKSet({\n *   keys: [\n *     {\n *       kty: 'RSA',\n *       e: 'AQAB',\n *       n: '12oBZRhCiZFJLcPg59LkZZ9mdhSMTKAQZYq32k_ti5SBB6jerkh-WzOMAO664r_qyLkqHUSp3u5SbXtseZEpN3XPWGKSxjsy-1JyEFTdLSYe6f9gfrmxkUF_7DTpq0gn6rntP05g2-wFW50YO7mosfdslfrTJYWHFhJALabAeYirYD7-9kqq9ebfFMF4sRRELbv9oi36As6Q9B3Qb5_C1rAzqfao_PCsf9EPsTZsVVVkA5qoIAr47lo1ipfiBPxUCCNSdvkmDTYgvvRm6ZoMjFbvOtgyts55fXKdMWv7I9HMD5HwE9uW839PWA514qhbcIsXEYSFMPMV6fnlsiZvQQ',\n *       alg: 'PS256',\n *     },\n *     {\n *       crv: 'P-256',\n *       kty: 'EC',\n *       x: 'ySK38C1jBdLwDsNWKzzBHqKYEE5Cgv-qjWvorUXk9fw',\n *       y: '_LeQBw07cf5t57Iavn4j-BqJsAD1dpoz8gokd3sBsOo',\n *       alg: 'ES256',\n *     },\n *   ],\n * })\n *\n * const { payload, protectedHeader } = await jose.jwtVerify(jwt, JWKS, {\n *   issuer: 'urn:example:issuer',\n *   audience: 'urn:example:audience',\n * })\n * console.log(protectedHeader)\n * console.log(payload)\n * ```\n *\n * @example\n *\n * Opting-in to multiple JWKS matches using `createLocalJWKSet`\n *\n * ```js\n * const options = {\n *   issuer: 'urn:example:issuer',\n *   audience: 'urn:example:audience',\n * }\n * const { payload, protectedHeader } = await jose\n *   .jwtVerify(jwt, JWKS, options)\n *   .catch(async (error) => {\n *     if (error?.code === 'ERR_JWKS_MULTIPLE_MATCHING_KEYS') {\n *       for await (const publicKey of error) {\n *         try {\n *           return await jose.jwtVerify(jwt, publicKey, options)\n *         } catch (innerError) {\n *           if (innerError?.code === 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') {\n *             continue\n *           }\n *           throw innerError\n *         }\n *       }\n *       throw new jose.errors.JWSSignatureVerificationFailed()\n *     }\n *\n *     throw error\n *   })\n * console.log(protectedHeader)\n * console.log(payload)\n * ```\n *\n * @param jwks JSON Web Key Set formatted object.\n */\nexport function createLocalJWKSet(\n  jwks: types.JSONWebKeySet,\n): (\n  protectedHeader?: types.JWSHeaderParameters,\n  token?: types.FlattenedJWSInput,\n) => Promise<types.CryptoKey> {\n  const set = new LocalJWKSet(jwks)\n\n  const localJWKSet = async (\n    protectedHeader?: types.JWSHeaderParameters,\n    token?: types.FlattenedJWSInput,\n  ): Promise<types.CryptoKey> => set.getKey(protectedHeader, token)\n\n  Object.defineProperties(localJWKSet, {\n    jwks: {\n      value: () => structuredClone(set.jwks()),\n      enumerable: false,\n      configurable: false,\n      writable: false,\n    },\n  })\n\n  return localJWKSet\n}\n"
  },
  {
    "path": "src/jwks/remote.ts",
    "content": "/**\n * Verification using a JSON Web Key Set (JWKS) available on an HTTP(S) URL\n *\n * @module\n */\n\nimport type * as types from '../types.d.ts'\nimport { JOSEError, JWKSNoMatchingKey, JWKSTimeout } from '../util/errors.js'\n\nimport { createLocalJWKSet } from './local.js'\nimport { isObject } from '../lib/type_checks.js'\n\nfunction isCloudflareWorkers() {\n  return (\n    // @ts-ignore\n    typeof WebSocketPair !== 'undefined' ||\n    // @ts-ignore\n    (typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers') ||\n    // @ts-ignore\n    (typeof EdgeRuntime !== 'undefined' && EdgeRuntime === 'vercel')\n  )\n}\n\n// An explicit user-agent in browser environment is a trigger for CORS preflight requests which\n// are not needed for our request, so we're omitting setting a default user-agent in browser\n// environments.\nlet USER_AGENT: string\n// @ts-ignore\nif (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {\n  const NAME = 'jose'\n  const VERSION = 'v6.2.2'\n  USER_AGENT = `${NAME}/${VERSION}`\n}\n\n/**\n * When passed to {@link jwks/remote.createRemoteJWKSet createRemoteJWKSet} this allows the resolver\n * to make use of advanced fetch configurations, HTTP Proxies, retry on network errors, etc.\n *\n * > [!NOTE]\\\n * > Known caveat: Expect Type-related issues when passing the inputs through to fetch-like modules,\n * > they hardly ever get their typings inline with actual fetch, you should `@ts-expect-error` them.\n *\n * @example\n *\n * Using [sindresorhus/ky](https://github.com/sindresorhus/ky) for retries and its hooks feature for\n * logging outgoing requests and their responses.\n *\n * ```ts\n * import ky from 'ky'\n *\n * let logRequest!: (request: Request) => void\n * let logResponse!: (request: Request, response: Response) => void\n * let logRetry!: (request: Request, error: Error, retryCount: number) => void\n *\n * const JWKS = jose.createRemoteJWKSet(url, {\n *   [jose.customFetch]: (...args) =>\n *     ky(args[0], {\n *       ...args[1],\n *       hooks: {\n *         beforeRequest: [\n *           (request) => {\n *             logRequest(request)\n *           },\n *         ],\n *         beforeRetry: [\n *           ({ request, error, retryCount }) => {\n *             logRetry(request, error, retryCount)\n *           },\n *         ],\n *         afterResponse: [\n *           (request, _, response) => {\n *             logResponse(request, response)\n *           },\n *         ],\n *       },\n *     }),\n * })\n * ```\n *\n * @example\n *\n * Using [nodejs/undici](https://github.com/nodejs/undici) to detect and use HTTP proxies.\n *\n * ```ts\n * import * as undici from 'undici'\n *\n * // see https://undici.nodejs.org/#/docs/api/EnvHttpProxyAgent\n * let envHttpProxyAgent = new undici.EnvHttpProxyAgent()\n *\n * // @ts-ignore\n * const JWKS = jose.createRemoteJWKSet(url, {\n *   [jose.customFetch]: (...args) => {\n *     // @ts-ignore\n *     return undici.fetch(args[0], { ...args[1], dispatcher: envHttpProxyAgent }) // prettier-ignore\n *   },\n * })\n * ```\n *\n * @example\n *\n * Using [nodejs/undici](https://github.com/nodejs/undici) to automatically retry network errors.\n *\n * ```ts\n * import * as undici from 'undici'\n *\n * // see https://undici.nodejs.org/#/docs/api/RetryAgent\n * let retryAgent = new undici.RetryAgent(new undici.Agent(), {\n *   statusCodes: [],\n *   errorCodes: [\n *     'ECONNRESET',\n *     'ECONNREFUSED',\n *     'ENOTFOUND',\n *     'ENETDOWN',\n *     'ENETUNREACH',\n *     'EHOSTDOWN',\n *     'UND_ERR_SOCKET',\n *   ],\n * })\n *\n * // @ts-ignore\n * const JWKS = jose.createRemoteJWKSet(url, {\n *   [jose.customFetch]: (...args) => {\n *     // @ts-ignore\n *     return undici.fetch(args[0], { ...args[1], dispatcher: retryAgent }) // prettier-ignore\n *   },\n * })\n * ```\n *\n * @example\n *\n * Using [nodejs/undici](https://github.com/nodejs/undici) to mock responses in tests.\n *\n * ```ts\n * import * as undici from 'undici'\n *\n * // see https://undici.nodejs.org/#/docs/api/MockAgent\n * let mockAgent = new undici.MockAgent()\n * mockAgent.disableNetConnect()\n *\n * // @ts-ignore\n * const JWKS = jose.createRemoteJWKSet(url, {\n *   [jose.customFetch]: (...args) => {\n *     // @ts-ignore\n *     return undici.fetch(args[0], { ...args[1], dispatcher: mockAgent }) // prettier-ignore\n *   },\n * })\n * ```\n */\nexport const customFetch: unique symbol = Symbol()\n\n/** See {@link customFetch}. */\nexport type FetchImplementation = (\n  /** URL the request is being made sent to {@link !fetch} as the `resource` argument */\n  url: string,\n  /** Options otherwise sent to {@link !fetch} as the `options` argument */\n  options: {\n    /** HTTP Headers */\n    headers: Headers\n    /** The {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods request method} */\n    method: 'GET'\n    /** See {@link !Request.redirect} */\n    redirect: 'manual'\n    signal: AbortSignal\n  },\n) => Promise<Response>\n\nasync function fetchJwks(\n  url: string,\n  headers: Headers,\n  signal: AbortSignal,\n  fetchImpl: FetchImplementation = fetch,\n) {\n  const response = await fetchImpl(url, {\n    method: 'GET',\n    signal,\n    redirect: 'manual',\n    headers,\n  }).catch((err) => {\n    if (err.name === 'TimeoutError') {\n      throw new JWKSTimeout()\n    }\n\n    throw err\n  })\n\n  if (response.status !== 200) {\n    throw new JOSEError('Expected 200 OK from the JSON Web Key Set HTTP response')\n  }\n\n  try {\n    return await response.json()\n  } catch {\n    throw new JOSEError('Failed to parse the JSON Web Key Set HTTP response as JSON')\n  }\n}\n\n/**\n * > [!WARNING]\\\n * > This option has security implications that must be understood, assessed for applicability, and\n * > accepted before use. It is critical that the JSON Web Key Set cache only be writable by your own\n * > code.\n *\n * This option is intended for cloud computing runtimes that cannot keep an in memory cache between\n * their code's invocations. Use in runtimes where an in memory cache between requests is available\n * is not desirable.\n *\n * When passed to {@link jwks/remote.createRemoteJWKSet createRemoteJWKSet} this allows the passed in\n * object to:\n *\n * - Serve as an initial value for the JSON Web Key Set that the module would otherwise need to\n *   trigger an HTTP request for\n * - Have the JSON Web Key Set the function optionally ended up triggering an HTTP request for\n *   assigned to it as properties\n *\n * The intended use pattern is:\n *\n * - Before verifying with {@link jwks/remote.createRemoteJWKSet createRemoteJWKSet} you pull the\n *   previously cached object from a low-latency key-value store offered by the cloud computing\n *   runtime it is executed on;\n * - Default to an empty object `{}` instead when there's no previously cached value;\n * - Pass it in as {@link RemoteJWKSetOptions[jwksCache]};\n * - Afterwards, update the key-value storage if the {@link ExportedJWKSCache.uat `uat`} property of\n *   the object has changed.\n *\n * @example\n *\n * ```ts\n * // Prerequisites\n * let url!: URL\n * let jwt!: string\n * let getPreviouslyCachedJWKS!: () => Promise<jose.ExportedJWKSCache>\n * let storeNewJWKScache!: (cache: jose.ExportedJWKSCache) => Promise<void>\n *\n * // Load JSON Web Key Set cache\n * const jwksCache: jose.JWKSCacheInput = (await getPreviouslyCachedJWKS()) || {}\n * const { uat } = jwksCache\n *\n * const JWKS = jose.createRemoteJWKSet(url, {\n *   [jose.jwksCache]: jwksCache,\n * })\n *\n * // Use JSON Web Key Set cache\n * await jose.jwtVerify(jwt, JWKS)\n *\n * if (uat !== jwksCache.uat) {\n *   // Update JSON Web Key Set cache\n *   await storeNewJWKScache(jwksCache)\n * }\n * ```\n */\nexport const jwksCache: unique symbol = Symbol()\n\n/** Options for the remote JSON Web Key Set. */\nexport interface RemoteJWKSetOptions {\n  /**\n   * Timeout (in milliseconds) for the HTTP request. When reached the request will be aborted and\n   * the verification will fail. Default is 5000 (5 seconds).\n   */\n  timeoutDuration?: number\n\n  /**\n   * Duration (in milliseconds) for which no more HTTP requests will be triggered after a previous\n   * successful fetch. Default is 30000 (30 seconds).\n   */\n  cooldownDuration?: number\n\n  /**\n   * Maximum time (in milliseconds) between successful HTTP requests. Default is 600000 (10\n   * minutes).\n   */\n  cacheMaxAge?: number | typeof Infinity\n\n  /** Headers to be sent with the HTTP request. */\n  headers?: Record<string, string>\n\n  /** See {@link jwksCache}. */\n  [jwksCache]?: JWKSCacheInput\n\n  /** See {@link customFetch}. */\n  [customFetch]?: FetchImplementation\n}\n\n/** See {@link jwksCache}. */\nexport interface ExportedJWKSCache {\n  /** Current cached JSON Web Key Set */\n  jwks: types.JSONWebKeySet\n  /** Last updated at timestamp (seconds since epoch) */\n  uat: number\n}\n\n/** See {@link jwksCache}. */\nexport type JWKSCacheInput = ExportedJWKSCache | Record<string, never>\n\nfunction isFreshJwksCache(input: unknown, cacheMaxAge: number): input is ExportedJWKSCache {\n  if (typeof input !== 'object' || input === null) {\n    return false\n  }\n\n  if (!('uat' in input) || typeof input.uat !== 'number' || Date.now() - input.uat >= cacheMaxAge) {\n    return false\n  }\n\n  if (\n    !('jwks' in input) ||\n    !isObject<types.JSONWebKeySet>(input.jwks) ||\n    !Array.isArray(input.jwks.keys) ||\n    !Array.prototype.every.call(input.jwks.keys, isObject)\n  ) {\n    return false\n  }\n\n  return true\n}\n\nclass RemoteJWKSet {\n  #url: URL\n\n  #timeoutDuration: number\n\n  #cooldownDuration: number\n\n  #cacheMaxAge: number\n\n  #jwksTimestamp?: number\n\n  #pendingFetch?: Promise<unknown>\n\n  #headers: Headers\n\n  #customFetch?: FetchImplementation\n\n  #local!: ReturnType<typeof createLocalJWKSet>\n\n  #cache?: JWKSCacheInput\n\n  constructor(url: unknown, options?: RemoteJWKSetOptions) {\n    if (!(url instanceof URL)) {\n      throw new TypeError('url must be an instance of URL')\n    }\n    this.#url = new URL(url.href)\n\n    this.#timeoutDuration =\n      typeof options?.timeoutDuration === 'number' ? options?.timeoutDuration : 5000\n    this.#cooldownDuration =\n      typeof options?.cooldownDuration === 'number' ? options?.cooldownDuration : 30000\n    this.#cacheMaxAge = typeof options?.cacheMaxAge === 'number' ? options?.cacheMaxAge : 600000\n    this.#headers = new Headers(options?.headers)\n    if (USER_AGENT && !this.#headers.has('User-Agent')) {\n      this.#headers.set('User-Agent', USER_AGENT)\n    }\n\n    if (!this.#headers.has('accept')) {\n      this.#headers.set('accept', 'application/json')\n      this.#headers.append('accept', 'application/jwk-set+json')\n    }\n\n    this.#customFetch = options?.[customFetch]\n\n    if (options?.[jwksCache] !== undefined) {\n      this.#cache = options?.[jwksCache]\n      if (isFreshJwksCache(options?.[jwksCache], this.#cacheMaxAge)) {\n        this.#jwksTimestamp = this.#cache.uat\n        this.#local = createLocalJWKSet(this.#cache.jwks)\n      }\n    }\n  }\n\n  pendingFetch(): boolean {\n    return !!this.#pendingFetch\n  }\n\n  coolingDown(): boolean {\n    return typeof this.#jwksTimestamp === 'number'\n      ? Date.now() < this.#jwksTimestamp + this.#cooldownDuration\n      : false\n  }\n\n  fresh(): boolean {\n    return typeof this.#jwksTimestamp === 'number'\n      ? Date.now() < this.#jwksTimestamp + this.#cacheMaxAge\n      : false\n  }\n\n  jwks(): types.JSONWebKeySet | undefined {\n    // @ts-expect-error\n    return this.#local?.jwks()\n  }\n\n  async getKey(\n    protectedHeader?: types.JWSHeaderParameters,\n    token?: types.FlattenedJWSInput,\n  ): Promise<types.CryptoKey> {\n    if (!this.#local || !this.fresh()) {\n      await this.reload()\n    }\n\n    try {\n      return await this.#local(protectedHeader, token)\n    } catch (err) {\n      if (err instanceof JWKSNoMatchingKey) {\n        if (this.coolingDown() === false) {\n          await this.reload()\n          return this.#local(protectedHeader, token)\n        }\n      }\n      throw err\n    }\n  }\n\n  async reload() {\n    // Do not assume a fetch created in another request reliably resolves\n    // see https://github.com/panva/jose/issues/355 and https://github.com/panva/jose/issues/509\n    if (this.#pendingFetch && isCloudflareWorkers()) {\n      this.#pendingFetch = undefined\n    }\n\n    this.#pendingFetch ||= fetchJwks(\n      this.#url.href,\n      this.#headers,\n      AbortSignal.timeout(this.#timeoutDuration),\n      this.#customFetch,\n    )\n      .then((json) => {\n        this.#local = createLocalJWKSet(json as unknown as types.JSONWebKeySet)\n        if (this.#cache) {\n          this.#cache.uat = Date.now()\n          this.#cache.jwks = json as unknown as types.JSONWebKeySet\n        }\n        this.#jwksTimestamp = Date.now()\n        this.#pendingFetch = undefined\n      })\n      .catch((err: Error) => {\n        this.#pendingFetch = undefined\n        throw err\n      })\n\n    await this.#pendingFetch\n  }\n}\n\n/**\n * Returns a function that resolves a JWS JOSE Header to a public key object downloaded from a\n * remote endpoint returning a JSON Web Key Set, that is, for example, an OAuth 2.0 or OIDC\n * jwks_uri. The JSON Web Key Set is fetched when no key matches the selection process but only as\n * frequently as the `cooldownDuration` option allows to prevent abuse.\n *\n * It uses the \"alg\" (JWS Algorithm) Header Parameter to determine the right JWK \"kty\" (Key Type),\n * then proceeds to match the JWK \"kid\" (Key ID) with one found in the JWS Header Parameters (if\n * there is one) while also respecting the JWK \"use\" (Public Key Use) and JWK \"key_ops\" (Key\n * Operations) Parameters (if they are present on the JWK).\n *\n * Only a single public key must match the selection process. As shown in the example below when\n * multiple keys get matched it is possible to opt-in to iterate over the matched keys and attempt\n * verification in an iterative manner.\n *\n * > [!NOTE]\\\n * > The function's purpose is to resolve public keys used for verifying signatures and will not work\n * > for public encryption keys.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/jwks/remote'`.\n *\n * @example\n *\n * ```js\n * const JWKS = jose.createRemoteJWKSet(new URL('https://www.googleapis.com/oauth2/v3/certs'))\n *\n * const { payload, protectedHeader } = await jose.jwtVerify(jwt, JWKS, {\n *   issuer: 'urn:example:issuer',\n *   audience: 'urn:example:audience',\n * })\n * console.log(protectedHeader)\n * console.log(payload)\n * ```\n *\n * @example\n *\n * Opting-in to multiple JWKS matches using `createRemoteJWKSet`\n *\n * ```js\n * const options = {\n *   issuer: 'urn:example:issuer',\n *   audience: 'urn:example:audience',\n * }\n * const { payload, protectedHeader } = await jose\n *   .jwtVerify(jwt, JWKS, options)\n *   .catch(async (error) => {\n *     if (error?.code === 'ERR_JWKS_MULTIPLE_MATCHING_KEYS') {\n *       for await (const publicKey of error) {\n *         try {\n *           return await jose.jwtVerify(jwt, publicKey, options)\n *         } catch (innerError) {\n *           if (innerError?.code === 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') {\n *             continue\n *           }\n *           throw innerError\n *         }\n *       }\n *       throw new jose.errors.JWSSignatureVerificationFailed()\n *     }\n *\n *     throw error\n *   })\n * console.log(protectedHeader)\n * console.log(payload)\n * ```\n *\n * @param url URL to fetch the JSON Web Key Set from.\n * @param options Options for the remote JSON Web Key Set.\n */\nexport function createRemoteJWKSet(\n  url: URL,\n  options?: RemoteJWKSetOptions,\n): {\n  (\n    protectedHeader?: types.JWSHeaderParameters,\n    token?: types.FlattenedJWSInput,\n  ): Promise<types.CryptoKey>\n  /** @ignore */\n  coolingDown: boolean\n  /** @ignore */\n  fresh: boolean\n  /** @ignore */\n  reloading: boolean\n  /** @ignore */\n  reload: () => Promise<void>\n  /** @ignore */\n  jwks: () => types.JSONWebKeySet | undefined\n} {\n  const set = new RemoteJWKSet(url, options)\n\n  const remoteJWKSet = async (\n    protectedHeader?: types.JWSHeaderParameters,\n    token?: types.FlattenedJWSInput,\n  ): Promise<types.CryptoKey> => set.getKey(protectedHeader, token)\n\n  Object.defineProperties(remoteJWKSet, {\n    coolingDown: {\n      get: () => set.coolingDown(),\n      enumerable: true,\n      configurable: false,\n    },\n    fresh: {\n      get: () => set.fresh(),\n      enumerable: true,\n      configurable: false,\n    },\n    reload: {\n      value: () => set.reload(),\n      enumerable: true,\n      configurable: false,\n      writable: false,\n    },\n    reloading: {\n      get: () => set.pendingFetch(),\n      enumerable: true,\n      configurable: false,\n    },\n    jwks: {\n      value: () => set.jwks(),\n      enumerable: true,\n      configurable: false,\n      writable: false,\n    },\n  })\n\n  // @ts-expect-error\n  return remoteJWKSet\n}\n"
  },
  {
    "path": "src/jws/compact/sign.ts",
    "content": "/**\n * Signing JSON Web Signature (JWS) in Compact Serialization\n *\n * @module\n */\n\nimport type * as types from '../../types.d.ts'\nimport { FlattenedSign } from '../flattened/sign.js'\n\n/**\n * The CompactSign class is used to build and sign Compact JWS strings.\n *\n * This class is exported (as a named export) from the main `'jose'` module entry point as well as\n * from its subpath export `'jose/jws/compact/sign'`.\n *\n * @example\n *\n * ```js\n * const jws = await new jose.CompactSign(\n *   new TextEncoder().encode('It’s a dangerous business, Frodo, going out your door.'),\n * )\n *   .setProtectedHeader({ alg: 'ES256' })\n *   .sign(privateKey)\n *\n * console.log(jws)\n * ```\n */\nexport class CompactSign {\n  #flattened: FlattenedSign\n\n  /**\n   * {@link CompactSign} constructor\n   *\n   * @param payload Binary representation of the payload to sign.\n   */\n  constructor(payload: Uint8Array) {\n    this.#flattened = new FlattenedSign(payload)\n  }\n\n  /**\n   * Sets the JWS Protected Header on the CompactSign object.\n   *\n   * @param protectedHeader JWS Protected Header.\n   */\n  setProtectedHeader(protectedHeader: types.CompactJWSHeaderParameters): this {\n    this.#flattened.setProtectedHeader(protectedHeader)\n    return this\n  }\n\n  /**\n   * Signs and resolves the value of the Compact JWS string.\n   *\n   * @param key Private Key or Secret to sign the JWS with. See\n   *   {@link https://github.com/panva/jose/issues/210#jws-alg Algorithm Key Requirements}.\n   * @param options JWS Sign options.\n   */\n  async sign(\n    key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n    options?: types.SignOptions,\n  ): Promise<string> {\n    const jws = await this.#flattened.sign(key, options)\n\n    if (jws.payload === undefined) {\n      throw new TypeError('use the flattened module for creating JWS with b64: false')\n    }\n\n    return `${jws.protected}.${jws.payload}.${jws.signature}`\n  }\n}\n"
  },
  {
    "path": "src/jws/compact/verify.ts",
    "content": "/**\n * Verifying JSON Web Signature (JWS) in Compact Serialization\n *\n * @module\n */\n\nimport type * as types from '../../types.d.ts'\nimport { flattenedVerify } from '../flattened/verify.js'\nimport { JWSInvalid } from '../../util/errors.js'\nimport { decoder } from '../../lib/buffer_utils.js'\n\n/**\n * Interface for Compact JWS Verification dynamic key resolution. No token components have been\n * verified at the time of this function call.\n *\n * @see {@link jwks/remote.createRemoteJWKSet createRemoteJWKSet} to verify using a remote JSON Web Key Set.\n */\nexport interface CompactVerifyGetKey extends types.GenericGetKeyFunction<\n  types.CompactJWSHeaderParameters,\n  types.FlattenedJWSInput,\n  types.CryptoKey | types.KeyObject | types.JWK | Uint8Array\n> {}\n\n/**\n * Verifies the signature and format of and afterwards decodes the Compact JWS.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/jws/compact/verify'`.\n *\n * @example\n *\n * ```js\n * const jws =\n *   'eyJhbGciOiJFUzI1NiJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4.kkAs_gPPxWMI3rHuVlxHaTPfDWDoqdI8jSvuSmqV-8IHIWXg9mcAeC9ggV-45ZHRbiRJ3obUIFo1rHphPA5URg'\n *\n * const { payload, protectedHeader } = await jose.compactVerify(jws, publicKey)\n *\n * console.log(protectedHeader)\n * console.log(new TextDecoder().decode(payload))\n * ```\n *\n * @param jws Compact JWS.\n * @param key Key to verify the JWS with. See\n *   {@link https://github.com/panva/jose/issues/210#jws-alg Algorithm Key Requirements}.\n * @param options JWS Verify options.\n */\nexport function compactVerify(\n  jws: string | Uint8Array,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n  options?: types.VerifyOptions,\n): Promise<types.CompactVerifyResult>\n/**\n * @param jws Compact JWS.\n * @param getKey Function resolving a key to verify the JWS with. See\n *   {@link https://github.com/panva/jose/issues/210#jws-alg Algorithm Key Requirements}.\n * @param options JWS Verify options.\n */\nexport function compactVerify(\n  jws: string | Uint8Array,\n  getKey: CompactVerifyGetKey,\n  options?: types.VerifyOptions,\n): Promise<types.CompactVerifyResult & types.ResolvedKey>\nexport async function compactVerify(\n  jws: string | Uint8Array,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array | CompactVerifyGetKey,\n  options?: types.VerifyOptions,\n) {\n  if (jws instanceof Uint8Array) {\n    jws = decoder.decode(jws)\n  }\n\n  if (typeof jws !== 'string') {\n    throw new JWSInvalid('Compact JWS must be a string or Uint8Array')\n  }\n  const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split('.')\n\n  if (length !== 3) {\n    throw new JWSInvalid('Invalid Compact JWS')\n  }\n\n  const verified = await flattenedVerify(\n    { payload, protected: protectedHeader, signature },\n    key as Parameters<typeof flattenedVerify>[1],\n    options,\n  )\n\n  const result = { payload: verified.payload, protectedHeader: verified.protectedHeader! }\n\n  if (typeof key === 'function') {\n    return { ...result, key: verified.key }\n  }\n\n  return result\n}\n"
  },
  {
    "path": "src/jws/flattened/sign.ts",
    "content": "/**\n * Signing JSON Web Signature (JWS) in Flattened JSON Serialization\n *\n * @module\n */\n\nimport type * as types from '../../types.d.ts'\nimport { encode as b64u } from '../../util/base64url.js'\nimport { sign } from '../../lib/signing.js'\n\nimport { isDisjoint } from '../../lib/type_checks.js'\nimport { JWSInvalid } from '../../util/errors.js'\nimport { concat, encode } from '../../lib/buffer_utils.js'\nimport { checkKeyType } from '../../lib/check_key_type.js'\nimport { validateCrit } from '../../lib/validate_crit.js'\nimport { normalizeKey } from '../../lib/normalize_key.js'\nimport { assertNotSet } from '../../lib/helpers.js'\n\n/**\n * The FlattenedSign class is used to build and sign Flattened JWS objects.\n *\n * This class is exported (as a named export) from the main `'jose'` module entry point as well as\n * from its subpath export `'jose/jws/flattened/sign'`.\n *\n * @example\n *\n * ```js\n * const jws = await new jose.FlattenedSign(\n *   new TextEncoder().encode('It’s a dangerous business, Frodo, going out your door.'),\n * )\n *   .setProtectedHeader({ alg: 'ES256' })\n *   .sign(privateKey)\n *\n * console.log(jws)\n * ```\n */\nexport class FlattenedSign {\n  #payload: Uint8Array\n\n  #protectedHeader!: types.JWSHeaderParameters\n\n  #unprotectedHeader!: types.JWSHeaderParameters\n\n  /**\n   * {@link FlattenedSign} constructor\n   *\n   * @param payload Binary representation of the payload to sign.\n   */\n  constructor(payload: Uint8Array) {\n    if (!(payload instanceof Uint8Array)) {\n      throw new TypeError('payload must be an instance of Uint8Array')\n    }\n    this.#payload = payload\n  }\n\n  /**\n   * Sets the JWS Protected Header on the FlattenedSign object.\n   *\n   * @param protectedHeader JWS Protected Header.\n   */\n  setProtectedHeader(protectedHeader: types.JWSHeaderParameters): this {\n    assertNotSet(this.#protectedHeader, 'setProtectedHeader')\n    this.#protectedHeader = protectedHeader\n    return this\n  }\n\n  /**\n   * Sets the JWS Unprotected Header on the FlattenedSign object.\n   *\n   * @param unprotectedHeader JWS Unprotected Header.\n   */\n  setUnprotectedHeader(unprotectedHeader: types.JWSHeaderParameters): this {\n    assertNotSet(this.#unprotectedHeader, 'setUnprotectedHeader')\n    this.#unprotectedHeader = unprotectedHeader\n    return this\n  }\n\n  /**\n   * Signs and resolves the value of the Flattened JWS object.\n   *\n   * @param key Private Key or Secret to sign the JWS with. See\n   *   {@link https://github.com/panva/jose/issues/210#jws-alg Algorithm Key Requirements}.\n   * @param options JWS Sign options.\n   */\n  async sign(\n    key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n    options?: types.SignOptions,\n  ): Promise<types.FlattenedJWS> {\n    if (!this.#protectedHeader && !this.#unprotectedHeader) {\n      throw new JWSInvalid(\n        'either setProtectedHeader or setUnprotectedHeader must be called before #sign()',\n      )\n    }\n\n    if (!isDisjoint(this.#protectedHeader, this.#unprotectedHeader)) {\n      throw new JWSInvalid(\n        'JWS Protected and JWS Unprotected Header Parameter names must be disjoint',\n      )\n    }\n\n    const joseHeader: types.JWSHeaderParameters = {\n      ...this.#protectedHeader,\n      ...this.#unprotectedHeader,\n    }\n\n    const extensions = validateCrit(\n      JWSInvalid,\n      new Map([['b64', true]]),\n      options?.crit,\n      this.#protectedHeader,\n      joseHeader,\n    )\n\n    let b64 = true\n    if (extensions.has('b64')) {\n      b64 = this.#protectedHeader.b64!\n      if (typeof b64 !== 'boolean') {\n        throw new JWSInvalid(\n          'The \"b64\" (base64url-encode payload) Header Parameter must be a boolean',\n        )\n      }\n    }\n\n    const { alg } = joseHeader\n\n    if (typeof alg !== 'string' || !alg) {\n      throw new JWSInvalid('JWS \"alg\" (Algorithm) Header Parameter missing or invalid')\n    }\n\n    checkKeyType(alg, key, 'sign')\n\n    let payloadS: string\n    let payloadB: Uint8Array\n    if (b64) {\n      payloadS = b64u(this.#payload)\n      payloadB = encode(payloadS)\n    } else {\n      payloadB = this.#payload\n      payloadS = ''\n    }\n\n    let protectedHeaderString: string\n    let protectedHeaderBytes: Uint8Array\n    if (this.#protectedHeader) {\n      protectedHeaderString = b64u(JSON.stringify(this.#protectedHeader))\n      protectedHeaderBytes = encode(protectedHeaderString)\n    } else {\n      protectedHeaderString = ''\n      protectedHeaderBytes = new Uint8Array()\n    }\n\n    const data = concat(protectedHeaderBytes, encode('.'), payloadB)\n\n    const k = await normalizeKey(key, alg)\n    const signature = await sign(alg, k, data)\n\n    const jws: types.FlattenedJWS = {\n      signature: b64u(signature),\n      payload: payloadS,\n    }\n\n    if (this.#unprotectedHeader) {\n      jws.header = this.#unprotectedHeader\n    }\n\n    if (this.#protectedHeader) {\n      jws.protected = protectedHeaderString\n    }\n\n    return jws\n  }\n}\n"
  },
  {
    "path": "src/jws/flattened/verify.ts",
    "content": "/**\n * Verifying JSON Web Signature (JWS) in Flattened JSON Serialization\n *\n * @module\n */\n\nimport type * as types from '../../types.d.ts'\nimport { decode as b64u } from '../../util/base64url.js'\nimport { verify } from '../../lib/signing.js'\n\nimport { JOSEAlgNotAllowed, JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js'\nimport { concat, encoder, decoder, encode } from '../../lib/buffer_utils.js'\nimport { decodeBase64url } from '../../lib/helpers.js'\nimport { isDisjoint } from '../../lib/type_checks.js'\nimport { isObject } from '../../lib/type_checks.js'\nimport { checkKeyType } from '../../lib/check_key_type.js'\nimport { validateCrit } from '../../lib/validate_crit.js'\nimport { validateAlgorithms } from '../../lib/validate_algorithms.js'\nimport { normalizeKey } from '../../lib/normalize_key.js'\n\n/**\n * Interface for Flattened JWS Verification dynamic key resolution. No token components have been\n * verified at the time of this function call.\n *\n * @see {@link jwks/remote.createRemoteJWKSet createRemoteJWKSet} to verify using a remote JSON Web Key Set.\n */\nexport interface FlattenedVerifyGetKey extends types.GenericGetKeyFunction<\n  types.JWSHeaderParameters | undefined,\n  types.FlattenedJWSInput,\n  types.CryptoKey | types.KeyObject | types.JWK | Uint8Array\n> {}\n\n/**\n * Verifies the signature and format of and afterwards decodes the Flattened JWS.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/jws/flattened/verify'`.\n *\n * @example\n *\n * ```js\n * const decoder = new TextDecoder()\n * const jws = {\n *   signature:\n *     'FVVOXwj6kD3DqdfD9yYqfT2W9jv-Nop4kOehp_DeDGNB5dQNSPRvntBY6xH3uxlCxE8na9d_kyhYOcanpDJ0EA',\n *   payload: 'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',\n *   protected: 'eyJhbGciOiJFUzI1NiJ9',\n * }\n *\n * const { payload, protectedHeader } = await jose.flattenedVerify(jws, publicKey)\n *\n * console.log(protectedHeader)\n * console.log(decoder.decode(payload))\n * ```\n *\n * @param jws Flattened JWS.\n * @param key Key to verify the JWS with. See\n *   {@link https://github.com/panva/jose/issues/210#jws-alg Algorithm Key Requirements}.\n * @param options JWS Verify options.\n */\nexport function flattenedVerify(\n  jws: types.FlattenedJWSInput,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n  options?: types.VerifyOptions,\n): Promise<types.FlattenedVerifyResult>\n/**\n * @param jws Flattened JWS.\n * @param getKey Function resolving a key to verify the JWS with. See\n *   {@link https://github.com/panva/jose/issues/210#jws-alg Algorithm Key Requirements}.\n * @param options JWS Verify options.\n */\nexport function flattenedVerify(\n  jws: types.FlattenedJWSInput,\n  getKey: FlattenedVerifyGetKey,\n  options?: types.VerifyOptions,\n): Promise<types.FlattenedVerifyResult & types.ResolvedKey>\nexport async function flattenedVerify(\n  jws: types.FlattenedJWSInput,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array | FlattenedVerifyGetKey,\n  options?: types.VerifyOptions,\n) {\n  if (!isObject(jws)) {\n    throw new JWSInvalid('Flattened JWS must be an object')\n  }\n\n  if (jws.protected === undefined && jws.header === undefined) {\n    throw new JWSInvalid('Flattened JWS must have either of the \"protected\" or \"header\" members')\n  }\n\n  if (jws.protected !== undefined && typeof jws.protected !== 'string') {\n    throw new JWSInvalid('JWS Protected Header incorrect type')\n  }\n\n  if (jws.payload === undefined) {\n    throw new JWSInvalid('JWS Payload missing')\n  }\n\n  if (typeof jws.signature !== 'string') {\n    throw new JWSInvalid('JWS Signature missing or incorrect type')\n  }\n\n  if (jws.header !== undefined && !isObject(jws.header)) {\n    throw new JWSInvalid('JWS Unprotected Header incorrect type')\n  }\n\n  let parsedProt: types.JWSHeaderParameters = {}\n  if (jws.protected) {\n    try {\n      const protectedHeader = b64u(jws.protected)\n      parsedProt = JSON.parse(decoder.decode(protectedHeader))\n    } catch {\n      throw new JWSInvalid('JWS Protected Header is invalid')\n    }\n  }\n  if (!isDisjoint(parsedProt, jws.header)) {\n    throw new JWSInvalid(\n      'JWS Protected and JWS Unprotected Header Parameter names must be disjoint',\n    )\n  }\n\n  const joseHeader: types.JWSHeaderParameters = {\n    ...parsedProt,\n    ...jws.header,\n  }\n\n  const extensions = validateCrit(\n    JWSInvalid,\n    new Map([['b64', true]]),\n    options?.crit,\n    parsedProt,\n    joseHeader,\n  )\n\n  let b64 = true\n  if (extensions.has('b64')) {\n    b64 = parsedProt.b64!\n    if (typeof b64 !== 'boolean') {\n      throw new JWSInvalid(\n        'The \"b64\" (base64url-encode payload) Header Parameter must be a boolean',\n      )\n    }\n  }\n\n  const { alg } = joseHeader\n\n  if (typeof alg !== 'string' || !alg) {\n    throw new JWSInvalid('JWS \"alg\" (Algorithm) Header Parameter missing or invalid')\n  }\n\n  const algorithms = options && validateAlgorithms('algorithms', options.algorithms)\n\n  if (algorithms && !algorithms.has(alg)) {\n    throw new JOSEAlgNotAllowed('\"alg\" (Algorithm) Header Parameter value not allowed')\n  }\n\n  if (b64) {\n    if (typeof jws.payload !== 'string') {\n      throw new JWSInvalid('JWS Payload must be a string')\n    }\n  } else if (typeof jws.payload !== 'string' && !(jws.payload instanceof Uint8Array)) {\n    throw new JWSInvalid('JWS Payload must be a string or an Uint8Array instance')\n  }\n\n  let resolvedKey = false\n  if (typeof key === 'function') {\n    key = await key(parsedProt, jws)\n    resolvedKey = true\n  }\n\n  checkKeyType(alg, key, 'verify')\n\n  const data = concat(\n    jws.protected !== undefined ? encode(jws.protected) : new Uint8Array(),\n    encode('.'),\n    typeof jws.payload === 'string'\n      ? b64\n        ? encode(jws.payload)\n        : encoder.encode(jws.payload)\n      : jws.payload,\n  )\n  const signature = decodeBase64url(jws.signature, 'signature', JWSInvalid)\n\n  const k = await normalizeKey(key, alg)\n  const verified = await verify(alg, k, signature, data)\n\n  if (!verified) {\n    throw new JWSSignatureVerificationFailed()\n  }\n\n  let payload: Uint8Array\n  if (b64) {\n    payload = decodeBase64url(jws.payload as string, 'payload', JWSInvalid)\n  } else if (typeof jws.payload === 'string') {\n    payload = encoder.encode(jws.payload)\n  } else {\n    payload = jws.payload\n  }\n\n  const result: types.FlattenedVerifyResult = { payload }\n\n  if (jws.protected !== undefined) {\n    result.protectedHeader = parsedProt\n  }\n\n  if (jws.header !== undefined) {\n    result.unprotectedHeader = jws.header\n  }\n\n  if (resolvedKey) {\n    return { ...result, key: k }\n  }\n\n  return result\n}\n"
  },
  {
    "path": "src/jws/general/sign.ts",
    "content": "/**\n * Signing JSON Web Signature (JWS) in General JSON Serialization\n *\n * @module\n */\n\nimport type * as types from '../../types.d.ts'\nimport { FlattenedSign } from '../flattened/sign.js'\nimport { JWSInvalid } from '../../util/errors.js'\nimport { assertNotSet } from '../../lib/helpers.js'\n\n/** Used to build General JWS object's individual signatures. */\nexport interface Signature {\n  /**\n   * Sets the JWS Protected Header on the Signature object.\n   *\n   * @param protectedHeader JWS Protected Header.\n   */\n  setProtectedHeader(protectedHeader: types.JWSHeaderParameters): Signature\n\n  /**\n   * Sets the JWS Unprotected Header on the Signature object.\n   *\n   * @param unprotectedHeader JWS Unprotected Header.\n   */\n  setUnprotectedHeader(unprotectedHeader: types.JWSHeaderParameters): Signature\n\n  /** A shorthand for calling addSignature() on the enclosing {@link GeneralSign} instance */\n  addSignature(...args: Parameters<GeneralSign['addSignature']>): Signature\n\n  /** A shorthand for calling encrypt() on the enclosing {@link GeneralSign} instance */\n  sign(...args: Parameters<GeneralSign['sign']>): Promise<types.GeneralJWS>\n\n  /** Returns the enclosing {@link GeneralSign} instance */\n  done(): GeneralSign\n}\n\nclass IndividualSignature implements Signature {\n  #parent: GeneralSign\n\n  protectedHeader?: types.JWSHeaderParameters\n  unprotectedHeader?: types.JWSHeaderParameters\n  options?: types.SignOptions\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array\n\n  constructor(\n    sig: GeneralSign,\n    key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n    options?: types.SignOptions,\n  ) {\n    this.#parent = sig\n    this.key = key\n    this.options = options\n  }\n\n  setProtectedHeader(protectedHeader: types.JWSHeaderParameters) {\n    assertNotSet(this.protectedHeader, 'setProtectedHeader')\n    this.protectedHeader = protectedHeader\n    return this\n  }\n\n  setUnprotectedHeader(unprotectedHeader: types.JWSHeaderParameters) {\n    assertNotSet(this.unprotectedHeader, 'setUnprotectedHeader')\n    this.unprotectedHeader = unprotectedHeader\n    return this\n  }\n\n  addSignature(...args: Parameters<GeneralSign['addSignature']>) {\n    return this.#parent.addSignature(...args)\n  }\n\n  sign(...args: Parameters<GeneralSign['sign']>) {\n    return this.#parent.sign(...args)\n  }\n\n  done() {\n    return this.#parent\n  }\n}\n\n/**\n * The GeneralSign class is used to build and sign General JWS objects.\n *\n * This class is exported (as a named export) from the main `'jose'` module entry point as well as\n * from its subpath export `'jose/jws/general/sign'`.\n *\n * @example\n *\n * ```js\n * const jws = await new jose.GeneralSign(\n *   new TextEncoder().encode('It’s a dangerous business, Frodo, going out your door.'),\n * )\n *   .addSignature(ecPrivateKey)\n *   .setProtectedHeader({ alg: 'ES256' })\n *   .addSignature(rsaPrivateKey)\n *   .setProtectedHeader({ alg: 'PS256' })\n *   .sign()\n *\n * console.log(jws)\n * ```\n */\nexport class GeneralSign {\n  #payload: Uint8Array\n\n  #signatures: IndividualSignature[] = []\n\n  /**\n   * {@link GeneralSign} constructor\n   *\n   * @param payload Binary representation of the payload to sign.\n   */\n  constructor(payload: Uint8Array) {\n    this.#payload = payload\n  }\n\n  /**\n   * Adds an additional signature for the General JWS object.\n   *\n   * @param key Private Key or Secret to sign the individual JWS signature with. See\n   *   {@link https://github.com/panva/jose/issues/210#jws-alg Algorithm Key Requirements}.\n   * @param options JWS Sign options.\n   */\n  addSignature(\n    key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n    options?: types.SignOptions,\n  ): Signature {\n    const signature = new IndividualSignature(this, key, options)\n    this.#signatures.push(signature)\n    return signature\n  }\n\n  /** Signs and resolves the value of the General JWS object. */\n  async sign(): Promise<types.GeneralJWS> {\n    if (!this.#signatures.length) {\n      throw new JWSInvalid('at least one signature must be added')\n    }\n\n    const jws: types.GeneralJWS = {\n      signatures: [],\n      payload: '',\n    }\n\n    for (let i = 0; i < this.#signatures.length; i++) {\n      const signature = this.#signatures[i]\n      const flattened = new FlattenedSign(this.#payload)\n\n      flattened.setProtectedHeader(signature.protectedHeader!)\n      flattened.setUnprotectedHeader(signature.unprotectedHeader!)\n\n      const { payload, ...rest } = await flattened.sign(signature.key, signature.options)\n      if (i === 0) {\n        jws.payload = payload\n      } else if (jws.payload !== payload) {\n        throw new JWSInvalid('inconsistent use of JWS Unencoded Payload (RFC7797)')\n      }\n      jws.signatures.push(rest)\n    }\n\n    return jws\n  }\n}\n"
  },
  {
    "path": "src/jws/general/verify.ts",
    "content": "/**\n * Verifying JSON Web Signature (JWS) in General JSON Serialization\n *\n * @module\n */\n\nimport type * as types from '../../types.d.ts'\nimport { flattenedVerify } from '../flattened/verify.js'\nimport { JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js'\nimport { isObject } from '../../lib/type_checks.js'\n\n/**\n * Interface for General JWS Verification dynamic key resolution. No token components have been\n * verified at the time of this function call.\n *\n * @see {@link jwks/remote.createRemoteJWKSet createRemoteJWKSet} to verify using a remote JSON Web Key Set.\n */\nexport interface GeneralVerifyGetKey extends types.GenericGetKeyFunction<\n  types.JWSHeaderParameters,\n  types.FlattenedJWSInput,\n  types.CryptoKey | types.KeyObject | types.JWK | Uint8Array\n> {}\n\n/**\n * Verifies the signature and format of and afterwards decodes the General JWS.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/jws/general/verify'`.\n *\n * > [!NOTE]\\\n * > The function iterates over the `signatures` array in the General JWS and returns the verification\n * > result of the first signature entry that can be successfully verified. The result only contains\n * > the payload, protected header, and unprotected header of that successfully verified signature\n * > entry. Other signature entries in the General JWS are not validated, and their headers are not\n * > included in the returned result. Recipients of a General JWS should only rely on the returned\n * > (verified) data.\n *\n * @example\n *\n * ```js\n * const jws = {\n *   payload: 'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',\n *   signatures: [\n *     {\n *       signature:\n *         'FVVOXwj6kD3DqdfD9yYqfT2W9jv-Nop4kOehp_DeDGNB5dQNSPRvntBY6xH3uxlCxE8na9d_kyhYOcanpDJ0EA',\n *       protected: 'eyJhbGciOiJFUzI1NiJ9',\n *     },\n *   ],\n * }\n *\n * const { payload, protectedHeader } = await jose.generalVerify(jws, publicKey)\n *\n * console.log(protectedHeader)\n * console.log(new TextDecoder().decode(payload))\n * ```\n *\n * @param jws General JWS.\n * @param key Key to verify the JWS with. See\n *   {@link https://github.com/panva/jose/issues/210#jws-alg Algorithm Key Requirements}.\n * @param options JWS Verify options.\n */\nexport function generalVerify(\n  jws: types.GeneralJWSInput,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n  options?: types.VerifyOptions,\n): Promise<types.GeneralVerifyResult>\n/**\n * @param jws General JWS.\n * @param getKey Function resolving a key to verify the JWS with. See\n *   {@link https://github.com/panva/jose/issues/210#jws-alg Algorithm Key Requirements}.\n * @param options JWS Verify options.\n */\nexport function generalVerify(\n  jws: types.GeneralJWSInput,\n  getKey: GeneralVerifyGetKey,\n  options?: types.VerifyOptions,\n): Promise<types.GeneralVerifyResult & types.ResolvedKey>\nexport async function generalVerify(\n  jws: types.GeneralJWSInput,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array | GeneralVerifyGetKey,\n  options?: types.VerifyOptions,\n) {\n  if (!isObject(jws)) {\n    throw new JWSInvalid('General JWS must be an object')\n  }\n\n  if (!Array.isArray(jws.signatures) || !jws.signatures.every(isObject)) {\n    throw new JWSInvalid('JWS Signatures missing or incorrect type')\n  }\n\n  for (const signature of jws.signatures) {\n    try {\n      return await flattenedVerify(\n        {\n          header: signature.header,\n          payload: jws.payload,\n          protected: signature.protected,\n          signature: signature.signature,\n        },\n        key as Parameters<typeof flattenedVerify>[1],\n        options,\n      )\n    } catch {\n      //\n    }\n  }\n  throw new JWSSignatureVerificationFailed()\n}\n"
  },
  {
    "path": "src/jwt/decrypt.ts",
    "content": "/**\n * JSON Web Token (JWT) Decryption (JWT is in JWE format)\n *\n * @module\n */\n\nimport type * as types from '../types.d.ts'\nimport { compactDecrypt } from '../jwe/compact/decrypt.js'\nimport { validateClaimsSet } from '../lib/jwt_claims_set.js'\nimport { JWTClaimValidationFailed } from '../util/errors.js'\n\n/** Combination of JWE Decryption options and JWT Claims Set verification options. */\nexport interface JWTDecryptOptions\n  extends types.DecryptOptions, types.JWTClaimVerificationOptions {}\n\n/**\n * Interface for JWT Decryption dynamic key resolution. No token components have been verified at\n * the time of this function call.\n */\nexport interface JWTDecryptGetKey extends types.GetKeyFunction<\n  types.CompactJWEHeaderParameters,\n  types.FlattenedJWE\n> {}\n\n/**\n * Verifies the JWT format (to be a JWE Compact format), decrypts the ciphertext, validates the JWT\n * Claims Set.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/jwt/decrypt'`.\n *\n * @example\n *\n * ```js\n * const secret = jose.base64url.decode('zH4NRP1HMALxxCFnRZABFA7GOJtzU_gIj02alfL1lvI')\n * const jwt =\n *   'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..MB66qstZBPxAXKdsjet_lA.WHbtJTl4taHp7otOHLq3hBvv0yNPsPEKHYInmCPdDDeyV1kU-f-tGEiU4FxlSqkqAT2hVs8_wMNiQFAzPU1PUgIqWCPsBrPP3TtxYsrtwagpn4SvCsUsx0Mhw9ZhliAO8CLmCBQkqr_T9AcYsz5uZw.7nX9m7BGUu_u1p1qFHzyIg'\n *\n * const { payload, protectedHeader } = await jose.jwtDecrypt(jwt, secret, {\n *   issuer: 'urn:example:issuer',\n *   audience: 'urn:example:audience',\n * })\n *\n * console.log(protectedHeader)\n * console.log(payload)\n * ```\n *\n * @param jwt JSON Web Token value (encoded as JWE).\n * @param key Private Key or Secret to decrypt and verify the JWT with. See\n *   {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}.\n * @param options JWT Decryption and JWT Claims Set validation options.\n */\nexport async function jwtDecrypt<PayloadType = types.JWTPayload>(\n  jwt: string | Uint8Array,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n  options?: JWTDecryptOptions,\n): Promise<types.JWTDecryptResult<PayloadType>>\n/**\n * @param jwt JSON Web Token value (encoded as JWE).\n * @param getKey Function resolving Private Key or Secret to decrypt and verify the JWT with. See\n *   {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}.\n * @param options JWT Decryption and JWT Claims Set validation options.\n */\nexport async function jwtDecrypt<PayloadType = types.JWTPayload>(\n  jwt: string | Uint8Array,\n  getKey: JWTDecryptGetKey,\n  options?: JWTDecryptOptions,\n): Promise<types.JWTDecryptResult<PayloadType> & types.ResolvedKey>\nexport async function jwtDecrypt(\n  jwt: string | Uint8Array,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array | JWTDecryptGetKey,\n  options?: JWTDecryptOptions,\n) {\n  const decrypted = await compactDecrypt(jwt, key as Parameters<typeof compactDecrypt>[1], options)\n  const payload = validateClaimsSet(decrypted.protectedHeader, decrypted.plaintext, options)\n\n  const { protectedHeader } = decrypted\n\n  if (protectedHeader.iss !== undefined && protectedHeader.iss !== payload.iss) {\n    throw new JWTClaimValidationFailed(\n      'replicated \"iss\" claim header parameter mismatch',\n      payload,\n      'iss',\n      'mismatch',\n    )\n  }\n\n  if (protectedHeader.sub !== undefined && protectedHeader.sub !== payload.sub) {\n    throw new JWTClaimValidationFailed(\n      'replicated \"sub\" claim header parameter mismatch',\n      payload,\n      'sub',\n      'mismatch',\n    )\n  }\n\n  if (\n    protectedHeader.aud !== undefined &&\n    JSON.stringify(protectedHeader.aud) !== JSON.stringify(payload.aud)\n  ) {\n    throw new JWTClaimValidationFailed(\n      'replicated \"aud\" claim header parameter mismatch',\n      payload,\n      'aud',\n      'mismatch',\n    )\n  }\n\n  const result = { payload, protectedHeader }\n\n  if (typeof key === 'function') {\n    return { ...result, key: decrypted.key }\n  }\n\n  return result\n}\n"
  },
  {
    "path": "src/jwt/encrypt.ts",
    "content": "/**\n * JSON Web Token (JWT) Encryption (JWT is in JWE format)\n *\n * @module\n */\n\nimport type * as types from '../types.d.ts'\nimport { CompactEncrypt } from '../jwe/compact/encrypt.js'\nimport { JWTClaimsBuilder } from '../lib/jwt_claims_set.js'\nimport { assertNotSet } from '../lib/helpers.js'\n\n/**\n * The EncryptJWT class is used to build and encrypt Compact JWE formatted JSON Web Tokens.\n *\n * This class is exported (as a named export) from the main `'jose'` module entry point as well as\n * from its subpath export `'jose/jwt/encrypt'`.\n *\n * @example\n *\n * ```js\n * const secret = jose.base64url.decode('zH4NRP1HMALxxCFnRZABFA7GOJtzU_gIj02alfL1lvI')\n * const jwt = await new jose.EncryptJWT({ 'urn:example:claim': true })\n *   .setProtectedHeader({ alg: 'dir', enc: 'A128CBC-HS256' })\n *   .setIssuedAt()\n *   .setIssuer('urn:example:issuer')\n *   .setAudience('urn:example:audience')\n *   .setExpirationTime('2h')\n *   .encrypt(secret)\n *\n * console.log(jwt)\n * ```\n */\nexport class EncryptJWT implements types.ProduceJWT {\n  #cek!: Uint8Array\n\n  #iv!: Uint8Array\n\n  #keyManagementParameters!: types.JWEKeyManagementHeaderParameters\n\n  #protectedHeader!: types.CompactJWEHeaderParameters\n\n  #replicateIssuerAsHeader!: boolean\n\n  #replicateSubjectAsHeader!: boolean\n\n  #replicateAudienceAsHeader!: boolean\n\n  #jwt: JWTClaimsBuilder\n\n  /**\n   * {@link EncryptJWT} constructor\n   *\n   * @param payload The JWT Claims Set object. Defaults to an empty object.\n   */\n  constructor(payload: types.JWTPayload = {}) {\n    this.#jwt = new JWTClaimsBuilder(payload)\n  }\n\n  setIssuer(issuer: string): this {\n    this.#jwt.iss = issuer\n    return this\n  }\n\n  setSubject(subject: string): this {\n    this.#jwt.sub = subject\n    return this\n  }\n\n  setAudience(audience: string | string[]): this {\n    this.#jwt.aud = audience\n    return this\n  }\n\n  setJti(jwtId: string): this {\n    this.#jwt.jti = jwtId\n    return this\n  }\n\n  setNotBefore(input: number | string | Date): this {\n    this.#jwt.nbf = input\n    return this\n  }\n\n  setExpirationTime(input: number | string | Date): this {\n    this.#jwt.exp = input\n    return this\n  }\n\n  setIssuedAt(input?: number | string | Date): this {\n    this.#jwt.iat = input\n    return this\n  }\n\n  /**\n   * Sets the JWE Protected Header on the EncryptJWT object.\n   *\n   * @param protectedHeader JWE Protected Header. Must contain an \"alg\" (JWE Algorithm) and \"enc\"\n   *   (JWE Encryption Algorithm) properties.\n   */\n  setProtectedHeader(protectedHeader: types.CompactJWEHeaderParameters): this {\n    assertNotSet(this.#protectedHeader, 'setProtectedHeader')\n    this.#protectedHeader = protectedHeader\n    return this\n  }\n\n  /**\n   * Sets the JWE Key Management parameters to be used when encrypting.\n   *\n   * (ECDH-ES) Use of this method is needed for ECDH based algorithms to set the \"apu\" (Agreement\n   * PartyUInfo) or \"apv\" (Agreement PartyVInfo) parameters.\n   *\n   * @param parameters JWE Key Management parameters.\n   */\n  setKeyManagementParameters(parameters: types.JWEKeyManagementHeaderParameters): this {\n    assertNotSet(this.#keyManagementParameters, 'setKeyManagementParameters')\n    this.#keyManagementParameters = parameters\n    return this\n  }\n\n  /**\n   * Sets a content encryption key to use, by default a random suitable one is generated for the JWE\n   * enc\" (Encryption Algorithm) Header Parameter.\n   *\n   * @deprecated You should not use this method. It is only really intended for test and vector\n   *   validation purposes.\n   *\n   * @param cek JWE Content Encryption Key.\n   */\n  setContentEncryptionKey(cek: Uint8Array): this {\n    assertNotSet(this.#cek, 'setContentEncryptionKey')\n    this.#cek = cek\n    return this\n  }\n\n  /**\n   * Sets the JWE Initialization Vector to use for content encryption, by default a random suitable\n   * one is generated for the JWE enc\" (Encryption Algorithm) Header Parameter.\n   *\n   * @deprecated You should not use this method. It is only really intended for test and vector\n   *   validation purposes.\n   *\n   * @param iv JWE Initialization Vector.\n   */\n  setInitializationVector(iv: Uint8Array): this {\n    assertNotSet(this.#iv, 'setInitializationVector')\n    this.#iv = iv\n    return this\n  }\n\n  /**\n   * Replicates the \"iss\" (Issuer) Claim as a JWE Protected Header Parameter.\n   *\n   * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-5.3 RFC7519#section-5.3}\n   */\n  replicateIssuerAsHeader(): this {\n    this.#replicateIssuerAsHeader = true\n    return this\n  }\n\n  /**\n   * Replicates the \"sub\" (Subject) Claim as a JWE Protected Header Parameter.\n   *\n   * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-5.3 RFC7519#section-5.3}\n   */\n  replicateSubjectAsHeader(): this {\n    this.#replicateSubjectAsHeader = true\n    return this\n  }\n\n  /**\n   * Replicates the \"aud\" (Audience) Claim as a JWE Protected Header Parameter.\n   *\n   * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-5.3 RFC7519#section-5.3}\n   */\n  replicateAudienceAsHeader(): this {\n    this.#replicateAudienceAsHeader = true\n    return this\n  }\n\n  /**\n   * Encrypts and returns the JWT.\n   *\n   * @param key Public Key or Secret to encrypt the JWT with. See\n   *   {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}.\n   * @param options JWE Encryption options.\n   */\n  async encrypt(\n    key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n    options?: types.EncryptOptions,\n  ): Promise<string> {\n    const enc = new CompactEncrypt(this.#jwt.data())\n    if (\n      this.#protectedHeader &&\n      (this.#replicateIssuerAsHeader ||\n        this.#replicateSubjectAsHeader ||\n        this.#replicateAudienceAsHeader)\n    ) {\n      this.#protectedHeader = {\n        ...this.#protectedHeader,\n        iss: this.#replicateIssuerAsHeader ? this.#jwt.iss : undefined,\n        sub: this.#replicateSubjectAsHeader ? this.#jwt.sub : undefined,\n        aud: this.#replicateAudienceAsHeader ? this.#jwt.aud : undefined,\n      }\n    }\n    enc.setProtectedHeader(this.#protectedHeader)\n    if (this.#iv) {\n      enc.setInitializationVector(this.#iv)\n    }\n    if (this.#cek) {\n      enc.setContentEncryptionKey(this.#cek)\n    }\n    if (this.#keyManagementParameters) {\n      enc.setKeyManagementParameters(this.#keyManagementParameters)\n    }\n    return enc.encrypt(key, options)\n  }\n}\n"
  },
  {
    "path": "src/jwt/sign.ts",
    "content": "/**\n * JSON Web Token (JWT) Signing (JWT is in JWS format)\n *\n * @module\n */\n\nimport { CompactSign } from '../jws/compact/sign.js'\nimport { JWTInvalid } from '../util/errors.js'\nimport type * as types from '../types.d.ts'\nimport { JWTClaimsBuilder } from '../lib/jwt_claims_set.js'\n\n/**\n * The SignJWT class is used to build and sign Compact JWS formatted JSON Web Tokens.\n *\n * This class is exported (as a named export) from the main `'jose'` module entry point as well as\n * from its subpath export `'jose/jwt/sign'`.\n *\n * @example\n *\n * Usage with a symmetric secret\n *\n * ```js\n * const secret = new TextEncoder().encode(\n *   'cc7e0d44fd473002f1c42167459001140ec6389b7353f8088f4d9a95f2f596f2',\n * )\n * const alg = 'HS256'\n *\n * const jwt = await new jose.SignJWT({ 'urn:example:claim': true })\n *   .setProtectedHeader({ alg })\n *   .setIssuedAt()\n *   .setIssuer('urn:example:issuer')\n *   .setAudience('urn:example:audience')\n *   .setExpirationTime('2h')\n *   .sign(secret)\n *\n * console.log(jwt)\n * ```\n *\n * @example\n *\n * Usage with a private PKCS#8 encoded RSA key\n *\n * ```js\n * const alg = 'RS256'\n * const pkcs8 = `-----BEGIN PRIVATE KEY-----\n * MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDCFg4UrY5xtulv\n * /NXKmL1J4qI1SopAfTNMo3X7p+kJO7plqUYjzaztcre1qfh0m33Sm1Q8oPbO/GpP\n * MU1/HgcceytgJ/b4UwufVVMl9BrMDYG8moDBylbVupFQS3Ly1L9i/iFG9Z9A9xzY\n * Zzf799A45bnvNXL6s2glzvjiRvfQ2NDF0anTcnZLcYtC7ugq1IMM+ihAcPfw8Qw2\n * chN/SmP4qAM+PKaQwagmU7doqmmyN9u38AfoYZ1GCFhEs5TBBT6H6h9YdHeVtiIq\n * 1c+fl03biSIfLrV7dUBD39gBmXBcL/30Ya3D82mCEUC4zg/UkOfQOmkmV3Lc8YUL\n * QZ8EJkBLAgMBAAECggEAVuVE/KEP6323WjpbBdAIv7HGahGrgGANvbxZsIhm34ls\n * VOPK0XDegZkhAybMZHjRhp+gwVxX5ChC+J3cUpOBH5FNxElgW6HizD2Jcq6t6LoL\n * YgPSrfEHm71iHg8JsgrqfUnGYFzMJmv88C6WdCtpgG/qJV1K00/Ly1G1QKoBffEs\n * +v4fAMJrCbUdCz1qWto+PU+HLMEo+krfEpGgcmtZeRlDADh8cETMQlgQfQX2VWq/\n * aAP4a1SXmo+j0cvRU4W5Fj0RVwNesIpetX2ZFz4p/JmB5sWFEj/fC7h5z2lq+6Bm\n * e2T3BHtXkIxoBW0/pYVnASC8P2puO5FnVxDmWuHDYQKBgQDTuuBd3+0tSFVEX+DU\n * 5qpFmHm5nyGItZRJTS+71yg5pBxq1KqNCUjAtbxR0q//fwauakh+BwRVCPOrqsUG\n * jBSb3NYE70Srp6elqxgkE54PwQx4Mr6exJPnseM9U4K+hULllf5yjM9edreJE1nV\n * NVgFjeyafQhrHKwgr7PERJ/ikwKBgQDqqsT1M+EJLmI1HtCspOG6cu7q3gf/wKRh\n * E8tu84i3YyBnI8uJkKy92RNVI5fvpBARe3tjSdM25rr2rcrcmF/5g6Q9ImxZPGCt\n * 86eOgO9ErNtbc4TEgybsP319UE4O41aKeNiBTAZKoYCxv/dMqG0j4avmWzd+foHq\n * gSNUvR2maQKBgQCYeqOsV2B6VPY7KIVFLd0AA9/dwvEmgAYLiA/RShDI+hwQ/5jX\n * uxDu37KAhqeC65sHLrmIMUt4Zdr+DRyZK3aIDNEAesPMjw/X6lCXYp1ZISD2yyym\n * MFGH8X8CIkstI9Faf9vf6PJKSFrC1/HA7wq17VCwrUzLvrljTMW8meM/CwKBgCpo\n * 2leGHLFQFKeM/iF1WuYbR1pi7gcmhY6VyTowARFDdOOu8GXYI5/bz0afvCGvAMho\n * DJCREv7lC/zww6zCTPYG+HOj+PjXlJFba3ixjIxYwPvyEJiDK1Ge18sB7Fl8dHNq\n * C5ayaqCqN1voWYUdGzxU2IA1E/5kVo5O8FesJeOhAoGBAImJbZFf+D5kA32Xxhac\n * 59lLWBCsocvvbd1cvDMNlRywAAyhsCb1SuX4nEAK9mrSBdfmoF2Nm3eilfsOds0f\n * K5mX069IKG82CMqh3Mzptd7e7lyb9lsoGO0BAtjho3cWtha/UZ70vfaMzGuZ6JmQ\n * ak6k+8+UFd93M4z0Qo74OhXB\n * -----END PRIVATE KEY-----`\n * const privateKey = await jose.importPKCS8(pkcs8, alg)\n *\n * const jwt = await new jose.SignJWT({ 'urn:example:claim': true })\n *   .setProtectedHeader({ alg })\n *   .setIssuedAt()\n *   .setIssuer('urn:example:issuer')\n *   .setAudience('urn:example:audience')\n *   .setExpirationTime('2h')\n *   .sign(privateKey)\n *\n * console.log(jwt)\n * ```\n *\n * @example\n *\n * Usage with a private JWK encoded RSA key\n *\n * ```js\n * const alg = 'RS256'\n * const jwk = {\n *   kty: 'RSA',\n *   n: 'whYOFK2Ocbbpb_zVypi9SeKiNUqKQH0zTKN1-6fpCTu6ZalGI82s7XK3tan4dJt90ptUPKD2zvxqTzFNfx4HHHsrYCf2-FMLn1VTJfQazA2BvJqAwcpW1bqRUEty8tS_Yv4hRvWfQPcc2Gc3-_fQOOW57zVy-rNoJc744kb30NjQxdGp03J2S3GLQu7oKtSDDPooQHD38PEMNnITf0pj-KgDPjymkMGoJlO3aKppsjfbt_AH6GGdRghYRLOUwQU-h-ofWHR3lbYiKtXPn5dN24kiHy61e3VAQ9_YAZlwXC_99GGtw_NpghFAuM4P1JDn0DppJldy3PGFC0GfBCZASw',\n *   e: 'AQAB',\n *   d: 'VuVE_KEP6323WjpbBdAIv7HGahGrgGANvbxZsIhm34lsVOPK0XDegZkhAybMZHjRhp-gwVxX5ChC-J3cUpOBH5FNxElgW6HizD2Jcq6t6LoLYgPSrfEHm71iHg8JsgrqfUnGYFzMJmv88C6WdCtpgG_qJV1K00_Ly1G1QKoBffEs-v4fAMJrCbUdCz1qWto-PU-HLMEo-krfEpGgcmtZeRlDADh8cETMQlgQfQX2VWq_aAP4a1SXmo-j0cvRU4W5Fj0RVwNesIpetX2ZFz4p_JmB5sWFEj_fC7h5z2lq-6Bme2T3BHtXkIxoBW0_pYVnASC8P2puO5FnVxDmWuHDYQ',\n *   p: '07rgXd_tLUhVRF_g1OaqRZh5uZ8hiLWUSU0vu9coOaQcatSqjQlIwLW8UdKv_38GrmpIfgcEVQjzq6rFBowUm9zWBO9Eq6enpasYJBOeD8EMeDK-nsST57HjPVOCvoVC5ZX-cozPXna3iRNZ1TVYBY3smn0IaxysIK-zxESf4pM',\n *   q: '6qrE9TPhCS5iNR7QrKThunLu6t4H_8CkYRPLbvOIt2MgZyPLiZCsvdkTVSOX76QQEXt7Y0nTNua69q3K3Jhf-YOkPSJsWTxgrfOnjoDvRKzbW3OExIMm7D99fVBODuNWinjYgUwGSqGAsb_3TKhtI-Gr5ls3fn6B6oEjVL0dpmk',\n *   dp: 'mHqjrFdgelT2OyiFRS3dAAPf3cLxJoAGC4gP0UoQyPocEP-Y17sQ7t-ygIanguubBy65iDFLeGXa_g0cmSt2iAzRAHrDzI8P1-pQl2KdWSEg9ssspjBRh_F_AiJLLSPRWn_b3-jySkhawtfxwO8Kte1QsK1My765Y0zFvJnjPws',\n *   dq: 'KmjaV4YcsVAUp4z-IXVa5htHWmLuByaFjpXJOjABEUN0467wZdgjn9vPRp-8Ia8AyGgMkJES_uUL_PDDrMJM9gb4c6P4-NeUkVtreLGMjFjA-_IQmIMrUZ7XywHsWXx0c2oLlrJqoKo3W-hZhR0bPFTYgDUT_mRWjk7wV6wl46E',\n *   qi: 'iYltkV_4PmQDfZfGFpzn2UtYEKyhy-9t3Vy8Mw2VHLAADKGwJvVK5ficQAr2atIF1-agXY2bd6KV-w52zR8rmZfTr0gobzYIyqHczOm13t7uXJv2WygY7QEC2OGjdxa2Fr9RnvS99ozMa5nomZBqTqT7z5QV33czjPRCjvg6FcE',\n * }\n * const privateKey = await jose.importJWK(jwk, alg)\n *\n * const jwt = await new jose.SignJWT({ 'urn:example:claim': true })\n *   .setProtectedHeader({ alg })\n *   .setIssuedAt()\n *   .setIssuer('urn:example:issuer')\n *   .setAudience('urn:example:audience')\n *   .setExpirationTime('2h')\n *   .sign(privateKey)\n *\n * console.log(jwt)\n * ```\n */\nexport class SignJWT implements types.ProduceJWT {\n  #protectedHeader!: types.JWTHeaderParameters\n\n  #jwt: JWTClaimsBuilder\n\n  /**\n   * {@link SignJWT} constructor\n   *\n   * @param payload The JWT Claims Set object. Defaults to an empty object.\n   */\n  constructor(payload: types.JWTPayload = {}) {\n    this.#jwt = new JWTClaimsBuilder(payload)\n  }\n\n  setIssuer(issuer: string): this {\n    this.#jwt.iss = issuer\n    return this\n  }\n\n  setSubject(subject: string): this {\n    this.#jwt.sub = subject\n    return this\n  }\n\n  setAudience(audience: string | string[]): this {\n    this.#jwt.aud = audience\n    return this\n  }\n\n  setJti(jwtId: string): this {\n    this.#jwt.jti = jwtId\n    return this\n  }\n\n  setNotBefore(input: number | string | Date): this {\n    this.#jwt.nbf = input\n    return this\n  }\n\n  setExpirationTime(input: number | string | Date): this {\n    this.#jwt.exp = input\n    return this\n  }\n\n  setIssuedAt(input?: number | string | Date): this {\n    this.#jwt.iat = input\n    return this\n  }\n\n  /**\n   * Sets the JWS Protected Header on the SignJWT object.\n   *\n   * @param protectedHeader JWS Protected Header. Must contain an \"alg\" (JWS Algorithm) property.\n   */\n  setProtectedHeader(protectedHeader: types.JWTHeaderParameters): this {\n    this.#protectedHeader = protectedHeader\n    return this\n  }\n\n  /**\n   * Signs and returns the JWT.\n   *\n   * @param key Private Key or Secret to sign the JWT with. See\n   *   {@link https://github.com/panva/jose/issues/210#jws-alg Algorithm Key Requirements}.\n   * @param options JWT Sign options.\n   */\n  async sign(\n    key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n    options?: types.SignOptions,\n  ): Promise<string> {\n    const sig = new CompactSign(this.#jwt.data())\n    sig.setProtectedHeader(this.#protectedHeader)\n    if (\n      Array.isArray(this.#protectedHeader?.crit) &&\n      this.#protectedHeader.crit.includes('b64') &&\n      // @ts-expect-error\n      this.#protectedHeader.b64 === false\n    ) {\n      throw new JWTInvalid('JWTs MUST NOT use unencoded payload')\n    }\n    return sig.sign(key, options)\n  }\n}\n"
  },
  {
    "path": "src/jwt/unsecured.ts",
    "content": "/**\n * Unsecured (unsigned & unencrypted) JSON Web Tokens (JWT)\n *\n * @module\n */\n\nimport * as b64u from '../util/base64url.js'\n\nimport type * as types from '../types.d.ts'\nimport { decoder } from '../lib/buffer_utils.js'\nimport { JWTInvalid } from '../util/errors.js'\nimport { validateClaimsSet, JWTClaimsBuilder } from '../lib/jwt_claims_set.js'\n\n/** Result of decoding an Unsecured JWT. */\nexport interface UnsecuredResult<PayloadType = types.JWTPayload> {\n  payload: PayloadType & types.JWTPayload\n  header: types.JWSHeaderParameters\n}\n\n/**\n * The UnsecuredJWT class is a utility for dealing with `{ \"alg\": \"none\" }` Unsecured JWTs.\n *\n * This class is exported (as a named export) from the main `'jose'` module entry point as well as\n * from its subpath export `'jose/jwt/unsecured'`.\n *\n * @example\n *\n * Encoding\n *\n * ```js\n * const unsecuredJwt = new jose.UnsecuredJWT({ 'urn:example:claim': true })\n *   .setIssuedAt()\n *   .setIssuer('urn:example:issuer')\n *   .setAudience('urn:example:audience')\n *   .setExpirationTime('2h')\n *   .encode()\n *\n * console.log(unsecuredJwt)\n * ```\n *\n * @example\n *\n * Decoding\n *\n * ```js\n * const payload = jose.UnsecuredJWT.decode(unsecuredJwt, {\n *   issuer: 'urn:example:issuer',\n *   audience: 'urn:example:audience',\n * })\n *\n * console.log(payload)\n * ```\n */\nexport class UnsecuredJWT implements types.ProduceJWT {\n  #jwt: JWTClaimsBuilder\n\n  /**\n   * {@link UnsecuredJWT} constructor\n   *\n   * @param payload The JWT Claims Set object. Defaults to an empty object.\n   */\n  constructor(payload: types.JWTPayload = {}) {\n    this.#jwt = new JWTClaimsBuilder(payload)\n  }\n\n  /** Encodes the Unsecured JWT. */\n  encode(): string {\n    const header = b64u.encode(JSON.stringify({ alg: 'none' }))\n    const payload = b64u.encode(this.#jwt.data())\n\n    return `${header}.${payload}.`\n  }\n\n  setIssuer(issuer: string): this {\n    this.#jwt.iss = issuer\n    return this\n  }\n\n  setSubject(subject: string): this {\n    this.#jwt.sub = subject\n    return this\n  }\n\n  setAudience(audience: string | string[]): this {\n    this.#jwt.aud = audience\n    return this\n  }\n\n  setJti(jwtId: string): this {\n    this.#jwt.jti = jwtId\n    return this\n  }\n\n  setNotBefore(input: number | string | Date): this {\n    this.#jwt.nbf = input\n    return this\n  }\n\n  setExpirationTime(input: number | string | Date): this {\n    this.#jwt.exp = input\n    return this\n  }\n\n  setIssuedAt(input?: number | string | Date): this {\n    this.#jwt.iat = input\n    return this\n  }\n\n  /**\n   * Decodes an unsecured JWT.\n   *\n   * @param jwt Unsecured JWT to decode the payload of.\n   * @param options JWT Claims Set validation options.\n   */\n  static decode<PayloadType = types.JWTPayload>(\n    jwt: string,\n    options?: types.JWTClaimVerificationOptions,\n  ): UnsecuredResult<PayloadType> {\n    if (typeof jwt !== 'string') {\n      throw new JWTInvalid('Unsecured JWT must be a string')\n    }\n    const { 0: encodedHeader, 1: encodedPayload, 2: signature, length } = jwt.split('.')\n\n    if (length !== 3 || signature !== '') {\n      throw new JWTInvalid('Invalid Unsecured JWT')\n    }\n\n    let header: types.JWSHeaderParameters\n    try {\n      header = JSON.parse(decoder.decode(b64u.decode(encodedHeader)))\n      if (header.alg !== 'none') throw new Error()\n    } catch {\n      throw new JWTInvalid('Invalid Unsecured JWT')\n    }\n\n    const payload = validateClaimsSet(\n      header,\n      b64u.decode(encodedPayload),\n      options,\n    ) as UnsecuredResult<PayloadType>['payload']\n\n    return { payload, header }\n  }\n}\n"
  },
  {
    "path": "src/jwt/verify.ts",
    "content": "/**\n * JSON Web Token (JWT) Verification (JWT is in JWS format)\n *\n * @module\n */\n\nimport { compactVerify } from '../jws/compact/verify.js'\nimport type * as types from '../types.d.ts'\nimport { validateClaimsSet } from '../lib/jwt_claims_set.js'\nimport { JWTInvalid } from '../util/errors.js'\n\n/** Combination of JWS Verification options and JWT Claims Set verification options. */\nexport interface JWTVerifyOptions extends types.VerifyOptions, types.JWTClaimVerificationOptions {}\n\n/**\n * Interface for JWT Verification dynamic key resolution. No token components have been verified at\n * the time of this function call.\n *\n * @see {@link jwks/remote.createRemoteJWKSet createRemoteJWKSet} to verify using a remote JSON Web Key Set.\n */\nexport interface JWTVerifyGetKey extends types.GenericGetKeyFunction<\n  types.JWTHeaderParameters,\n  types.FlattenedJWSInput,\n  types.CryptoKey | types.KeyObject | types.JWK | Uint8Array\n> {}\n\n/**\n * Verifies the JWT format (to be a JWS Compact format), verifies the JWS signature, validates the\n * JWT Claims Set.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/jwt/verify'`.\n *\n * @example\n *\n * Usage with a symmetric secret\n *\n * ```js\n * const secret = new TextEncoder().encode(\n *   'cc7e0d44fd473002f1c42167459001140ec6389b7353f8088f4d9a95f2f596f2',\n * )\n * const jwt =\n *   'eyJhbGciOiJIUzI1NiJ9.eyJ1cm46ZXhhbXBsZTpjbGFpbSI6dHJ1ZSwiaWF0IjoxNjY5MDU2MjMxLCJpc3MiOiJ1cm46ZXhhbXBsZTppc3N1ZXIiLCJhdWQiOiJ1cm46ZXhhbXBsZTphdWRpZW5jZSJ9.C4iSlLfAUMBq--wnC6VqD9gEOhwpRZpoRarE0m7KEnI'\n *\n * const { payload, protectedHeader } = await jose.jwtVerify(jwt, secret, {\n *   issuer: 'urn:example:issuer',\n *   audience: 'urn:example:audience',\n * })\n *\n * console.log(protectedHeader)\n * console.log(payload)\n * ```\n *\n * @example\n *\n * Usage with a public SPKI encoded RSA key\n *\n * ```js\n * const alg = 'RS256'\n * const spki = `-----BEGIN PUBLIC KEY-----\n * MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwhYOFK2Ocbbpb/zVypi9\n * SeKiNUqKQH0zTKN1+6fpCTu6ZalGI82s7XK3tan4dJt90ptUPKD2zvxqTzFNfx4H\n * HHsrYCf2+FMLn1VTJfQazA2BvJqAwcpW1bqRUEty8tS/Yv4hRvWfQPcc2Gc3+/fQ\n * OOW57zVy+rNoJc744kb30NjQxdGp03J2S3GLQu7oKtSDDPooQHD38PEMNnITf0pj\n * +KgDPjymkMGoJlO3aKppsjfbt/AH6GGdRghYRLOUwQU+h+ofWHR3lbYiKtXPn5dN\n * 24kiHy61e3VAQ9/YAZlwXC/99GGtw/NpghFAuM4P1JDn0DppJldy3PGFC0GfBCZA\n * SwIDAQAB\n * -----END PUBLIC KEY-----`\n * const publicKey = await jose.importSPKI(spki, alg)\n * const jwt =\n *   'eyJhbGciOiJSUzI1NiJ9.eyJ1cm46ZXhhbXBsZTpjbGFpbSI6dHJ1ZSwiaWF0IjoxNjY5MDU2NDg4LCJpc3MiOiJ1cm46ZXhhbXBsZTppc3N1ZXIiLCJhdWQiOiJ1cm46ZXhhbXBsZTphdWRpZW5jZSJ9.gXrPZ3yM_60dMXGE69dusbpzYASNA-XIOwsb5D5xYnSxyj6_D6OR_uR_1vqhUm4AxZxcrH1_-XJAve9HCw8az_QzHcN-nETt-v6stCsYrn6Bv1YOc-mSJRZ8ll57KVqLbCIbjKwerNX5r2_Qg2TwmJzQdRs-AQDhy-s_DlJd8ql6wR4n-kDZpar-pwIvz4fFIN0Fj57SXpAbLrV6Eo4Byzl0xFD8qEYEpBwjrMMfxCZXTlAVhAq6KCoGlDTwWuExps342-0UErEtyIqDnDGcrfNWiUsoo8j-29IpKd-w9-C388u-ChCxoHz--H8WmMSZzx3zTXsZ5lXLZ9IKfanDKg'\n *\n * const { payload, protectedHeader } = await jose.jwtVerify(jwt, publicKey, {\n *   issuer: 'urn:example:issuer',\n *   audience: 'urn:example:audience',\n * })\n *\n * console.log(protectedHeader)\n * console.log(payload)\n * ```\n *\n * @example\n *\n * Usage with a public JWK encoded RSA key\n *\n * ```js\n * const alg = 'RS256'\n * const jwk = {\n *   kty: 'RSA',\n *   n: 'whYOFK2Ocbbpb_zVypi9SeKiNUqKQH0zTKN1-6fpCTu6ZalGI82s7XK3tan4dJt90ptUPKD2zvxqTzFNfx4HHHsrYCf2-FMLn1VTJfQazA2BvJqAwcpW1bqRUEty8tS_Yv4hRvWfQPcc2Gc3-_fQOOW57zVy-rNoJc744kb30NjQxdGp03J2S3GLQu7oKtSDDPooQHD38PEMNnITf0pj-KgDPjymkMGoJlO3aKppsjfbt_AH6GGdRghYRLOUwQU-h-ofWHR3lbYiKtXPn5dN24kiHy61e3VAQ9_YAZlwXC_99GGtw_NpghFAuM4P1JDn0DppJldy3PGFC0GfBCZASw',\n *   e: 'AQAB',\n * }\n * const publicKey = await jose.importJWK(jwk, alg)\n * const jwt =\n *   'eyJhbGciOiJSUzI1NiJ9.eyJ1cm46ZXhhbXBsZTpjbGFpbSI6dHJ1ZSwiaWF0IjoxNjY5MDU2NDg4LCJpc3MiOiJ1cm46ZXhhbXBsZTppc3N1ZXIiLCJhdWQiOiJ1cm46ZXhhbXBsZTphdWRpZW5jZSJ9.gXrPZ3yM_60dMXGE69dusbpzYASNA-XIOwsb5D5xYnSxyj6_D6OR_uR_1vqhUm4AxZxcrH1_-XJAve9HCw8az_QzHcN-nETt-v6stCsYrn6Bv1YOc-mSJRZ8ll57KVqLbCIbjKwerNX5r2_Qg2TwmJzQdRs-AQDhy-s_DlJd8ql6wR4n-kDZpar-pwIvz4fFIN0Fj57SXpAbLrV6Eo4Byzl0xFD8qEYEpBwjrMMfxCZXTlAVhAq6KCoGlDTwWuExps342-0UErEtyIqDnDGcrfNWiUsoo8j-29IpKd-w9-C388u-ChCxoHz--H8WmMSZzx3zTXsZ5lXLZ9IKfanDKg'\n *\n * const { payload, protectedHeader } = await jose.jwtVerify(jwt, publicKey, {\n *   issuer: 'urn:example:issuer',\n *   audience: 'urn:example:audience',\n * })\n *\n * console.log(protectedHeader)\n * console.log(payload)\n * ```\n *\n * @param jwt JSON Web Token value (encoded as JWS).\n * @param key Key to verify the JWT with. See\n *   {@link https://github.com/panva/jose/issues/210#jws-alg Algorithm Key Requirements}.\n * @param options JWT Decryption and JWT Claims Set validation options.\n */\nexport async function jwtVerify<PayloadType = types.JWTPayload>(\n  jwt: string | Uint8Array,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n  options?: JWTVerifyOptions,\n): Promise<types.JWTVerifyResult<PayloadType>>\n\n/**\n * @example\n *\n * Usage with a public JSON Web Key Set hosted on a remote URL\n *\n * ```js\n * const JWKS = jose.createRemoteJWKSet(new URL('https://www.googleapis.com/oauth2/v3/certs'))\n *\n * const { payload, protectedHeader } = await jose.jwtVerify(jwt, JWKS, {\n *   issuer: 'urn:example:issuer',\n *   audience: 'urn:example:audience',\n * })\n * console.log(protectedHeader)\n * console.log(payload)\n * ```\n *\n * @param jwt JSON Web Token value (encoded as JWS).\n * @param getKey Function resolving a key to verify the JWT with. See\n *   {@link https://github.com/panva/jose/issues/210#jws-alg Algorithm Key Requirements}.\n * @param options JWT Decryption and JWT Claims Set validation options.\n */\nexport async function jwtVerify<PayloadType = types.JWTPayload>(\n  jwt: string | Uint8Array,\n  getKey: JWTVerifyGetKey,\n  options?: JWTVerifyOptions,\n): Promise<types.JWTVerifyResult<PayloadType> & types.ResolvedKey>\n\nexport async function jwtVerify(\n  jwt: string | Uint8Array,\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array | JWTVerifyGetKey,\n  options?: JWTVerifyOptions,\n) {\n  const verified = await compactVerify(jwt, key as Parameters<typeof compactVerify>[1], options)\n  if (verified.protectedHeader.crit?.includes('b64') && verified.protectedHeader.b64 === false) {\n    throw new JWTInvalid('JWTs MUST NOT use unencoded payload')\n  }\n  const payload = validateClaimsSet(verified.protectedHeader, verified.payload, options)\n  const result = { payload, protectedHeader: verified.protectedHeader }\n  if (typeof key === 'function') {\n    return { ...result, key: verified.key }\n  }\n  return result\n}\n"
  },
  {
    "path": "src/key/export.ts",
    "content": "/**\n * Cryptographic key export functions\n *\n * @module\n */\n\nimport { toSPKI as exportPublic, toPKCS8 as exportPrivate } from '../lib/asn1.js'\nimport { keyToJWK } from '../lib/key_to_jwk.js'\n\nimport type * as types from '../types.d.ts'\n\n/**\n * Exports a public {@link !CryptoKey} or {@link !KeyObject} to a PEM-encoded SPKI string format.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/key/export'`.\n *\n * @example\n *\n * ```js\n * const spkiPem = await jose.exportSPKI(publicKey)\n *\n * console.log(spkiPem)\n * ```\n *\n * @param key Key to export to a PEM-encoded SPKI string format.\n */\nexport async function exportSPKI(key: types.CryptoKey | types.KeyObject): Promise<string> {\n  return exportPublic(key)\n}\n\n/**\n * Exports a private {@link !CryptoKey} or {@link !KeyObject} to a PEM-encoded PKCS8 string format.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/key/export'`.\n *\n * @example\n *\n * ```js\n * const pkcs8Pem = await jose.exportPKCS8(privateKey)\n *\n * console.log(pkcs8Pem)\n * ```\n *\n * @param key Key to export to a PEM-encoded PKCS8 string format.\n */\nexport async function exportPKCS8(key: types.CryptoKey | types.KeyObject): Promise<string> {\n  return exportPrivate(key)\n}\n\n/**\n * Exports a {@link !CryptoKey}, {@link !KeyObject}, or {@link !Uint8Array} to a JWK.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/key/export'`.\n *\n * @example\n *\n * ```js\n * const privateJwk = await jose.exportJWK(privateKey)\n * const publicJwk = await jose.exportJWK(publicKey)\n *\n * console.log(privateJwk)\n * console.log(publicJwk)\n * ```\n *\n * @param key Key to export as JWK.\n */\nexport async function exportJWK(\n  key: types.CryptoKey | types.KeyObject | Uint8Array,\n): Promise<types.JWK> {\n  return keyToJWK(key)\n}\n"
  },
  {
    "path": "src/key/generate_key_pair.ts",
    "content": "/**\n * Asymmetric key generation\n *\n * @module\n */\n\nimport { JOSENotSupported } from '../util/errors.js'\n\nimport type * as types from '../types.d.ts'\n\n/** Asymmetric key pair generation function result. */\nexport interface GenerateKeyPairResult {\n  /** The generated Private Key. */\n  privateKey: types.CryptoKey\n\n  /** Public Key corresponding to the generated Private Key. */\n  publicKey: types.CryptoKey\n}\n\n/** Asymmetric key pair generation function options. */\nexport interface GenerateKeyPairOptions {\n  /**\n   * The EC \"crv\" (Curve) or OKP \"crv\" (Subtype of Key Pair) value to generate. The curve must be\n   * both supported on the runtime as well as applicable for the given JWA algorithm identifier.\n   */\n  crv?: string\n\n  /**\n   * A hint for RSA algorithms to generate an RSA key of a given `modulusLength` (Key size in bits).\n   * JOSE requires 2048 bits or larger. Default is 2048.\n   */\n  modulusLength?: number\n\n  /**\n   * The value to use as {@link !SubtleCrypto.generateKey} `extractable` argument. Default is false.\n   *\n   * @example\n   *\n   * ```js\n   * const { publicKey, privateKey } = await jose.generateKeyPair('PS256', {\n   *   extractable: true,\n   * })\n   * console.log(await jose.exportJWK(privateKey))\n   * console.log(await jose.exportPKCS8(privateKey))\n   * ```\n   */\n  extractable?: boolean\n}\n\nfunction getModulusLengthOption(options?: GenerateKeyPairOptions) {\n  const modulusLength = options?.modulusLength ?? 2048\n  if (typeof modulusLength !== 'number' || modulusLength < 2048) {\n    throw new JOSENotSupported(\n      'Invalid or unsupported modulusLength option provided, 2048 bits or larger keys must be used',\n    )\n  }\n  return modulusLength\n}\n\n/**\n * Generates a private and a public key for a given JWA algorithm identifier. This can only generate\n * asymmetric key pairs. For symmetric secrets use the `generateSecret` function.\n *\n * > [!NOTE]\\\n * > The `privateKey` is generated with `extractable` set to `false` by default. See\n * > {@link GenerateKeyPairOptions.extractable} to generate an extractable `privateKey`.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/generate/keypair'`.\n *\n * @example\n *\n * ```js\n * const { publicKey, privateKey } = await jose.generateKeyPair('PS256')\n * console.log(publicKey)\n * console.log(privateKey)\n * ```\n *\n * @param alg JWA Algorithm Identifier to be used with the generated key pair. See\n *   {@link https://github.com/panva/jose/issues/210 Algorithm Key Requirements}.\n * @param options Additional options passed down to the key pair generation.\n */\nexport async function generateKeyPair(\n  alg: string,\n  options?: GenerateKeyPairOptions,\n): Promise<GenerateKeyPairResult> {\n  let algorithm: RsaHashedKeyGenParams | EcKeyGenParams | KeyAlgorithm\n  let keyUsages: KeyUsage[]\n\n  switch (alg) {\n    case 'PS256':\n    case 'PS384':\n    case 'PS512':\n      algorithm = {\n        name: 'RSA-PSS',\n        hash: `SHA-${alg.slice(-3)}`,\n        publicExponent: Uint8Array.of(0x01, 0x00, 0x01),\n        modulusLength: getModulusLengthOption(options),\n      }\n      keyUsages = ['sign', 'verify']\n      break\n    case 'RS256':\n    case 'RS384':\n    case 'RS512':\n      algorithm = {\n        name: 'RSASSA-PKCS1-v1_5',\n        hash: `SHA-${alg.slice(-3)}`,\n        publicExponent: Uint8Array.of(0x01, 0x00, 0x01),\n        modulusLength: getModulusLengthOption(options),\n      }\n      keyUsages = ['sign', 'verify']\n      break\n    case 'RSA-OAEP':\n    case 'RSA-OAEP-256':\n    case 'RSA-OAEP-384':\n    case 'RSA-OAEP-512':\n      algorithm = {\n        name: 'RSA-OAEP',\n        hash: `SHA-${parseInt(alg.slice(-3), 10) || 1}`,\n        publicExponent: Uint8Array.of(0x01, 0x00, 0x01),\n        modulusLength: getModulusLengthOption(options),\n      }\n      keyUsages = ['decrypt', 'unwrapKey', 'encrypt', 'wrapKey']\n      break\n    case 'ES256':\n      algorithm = { name: 'ECDSA', namedCurve: 'P-256' }\n      keyUsages = ['sign', 'verify']\n      break\n    case 'ES384':\n      algorithm = { name: 'ECDSA', namedCurve: 'P-384' }\n      keyUsages = ['sign', 'verify']\n      break\n    case 'ES512':\n      algorithm = { name: 'ECDSA', namedCurve: 'P-521' }\n      keyUsages = ['sign', 'verify']\n      break\n    case 'Ed25519': // Fall through\n    case 'EdDSA': {\n      keyUsages = ['sign', 'verify']\n      algorithm = { name: 'Ed25519' }\n      break\n    }\n    case 'ML-DSA-44':\n    case 'ML-DSA-65':\n    case 'ML-DSA-87': {\n      keyUsages = ['sign', 'verify']\n      algorithm = { name: alg }\n      break\n    }\n    case 'ECDH-ES':\n    case 'ECDH-ES+A128KW':\n    case 'ECDH-ES+A192KW':\n    case 'ECDH-ES+A256KW': {\n      keyUsages = ['deriveBits']\n      const crv = options?.crv ?? 'P-256'\n      switch (crv) {\n        case 'P-256':\n        case 'P-384':\n        case 'P-521': {\n          algorithm = { name: 'ECDH', namedCurve: crv }\n          break\n        }\n        case 'X25519':\n          algorithm = { name: 'X25519' }\n          break\n        default:\n          throw new JOSENotSupported(\n            'Invalid or unsupported crv option provided, supported values are P-256, P-384, P-521, and X25519',\n          )\n      }\n      break\n    }\n    default:\n      throw new JOSENotSupported('Invalid or unsupported JWK \"alg\" (Algorithm) Parameter value')\n  }\n\n  return crypto.subtle.generateKey(\n    algorithm,\n    options?.extractable ?? false,\n    keyUsages,\n  ) as Promise<GenerateKeyPairResult>\n}\n"
  },
  {
    "path": "src/key/generate_secret.ts",
    "content": "/**\n * Symmetric key generation\n *\n * @module\n */\n\nimport { JOSENotSupported } from '../util/errors.js'\n\nimport type * as types from '../types.d.ts'\n\n/** Secret generation function options. */\nexport interface GenerateSecretOptions {\n  /**\n   * The value to use as {@link !SubtleCrypto.generateKey} `extractable` argument. Default is false.\n   *\n   * > [!NOTE]\\\n   * > Because A128CBC-HS256, A192CBC-HS384, and A256CBC-HS512 secrets cannot be represented as\n   * > {@link !CryptoKey} this option has no effect for them.\n   */\n  extractable?: boolean\n}\n\n/**\n * Generates a symmetric secret key for a given JWA algorithm identifier.\n *\n * > [!NOTE]\\\n * > The secret key is generated with `extractable` set to `false` by default.\n *\n * > [!NOTE]\\\n * > Because A128CBC-HS256, A192CBC-HS384, and A256CBC-HS512 secrets cannot be represented as\n * > {@link !CryptoKey} this method yields a {@link !Uint8Array} for them instead.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/generate/secret'`.\n *\n * @example\n *\n * ```js\n * const secret = await jose.generateSecret('HS256')\n * console.log(secret)\n * ```\n *\n * @param alg JWA Algorithm Identifier to be used with the generated secret. See\n *   {@link https://github.com/panva/jose/issues/210 Algorithm Key Requirements}.\n * @param options Additional options passed down to the secret generation.\n */\nexport async function generateSecret(\n  alg: string,\n  options?: GenerateSecretOptions,\n): Promise<types.CryptoKey | Uint8Array> {\n  let length: number\n  let algorithm: AesKeyGenParams | HmacKeyGenParams\n  let keyUsages: KeyUsage[]\n  switch (alg) {\n    case 'HS256':\n    case 'HS384':\n    case 'HS512':\n      length = parseInt(alg.slice(-3), 10)\n      algorithm = { name: 'HMAC', hash: `SHA-${length}`, length }\n      keyUsages = ['sign', 'verify']\n      break\n    case 'A128CBC-HS256':\n    case 'A192CBC-HS384':\n    case 'A256CBC-HS512':\n      length = parseInt(alg.slice(-3), 10)\n      return crypto.getRandomValues(new Uint8Array(length >> 3))\n    case 'A128KW':\n    case 'A192KW':\n    case 'A256KW':\n      length = parseInt(alg.slice(1, 4), 10)\n      algorithm = { name: 'AES-KW', length }\n      keyUsages = ['wrapKey', 'unwrapKey']\n      break\n    case 'A128GCMKW':\n    case 'A192GCMKW':\n    case 'A256GCMKW':\n    case 'A128GCM':\n    case 'A192GCM':\n    case 'A256GCM':\n      length = parseInt(alg.slice(1, 4), 10)\n      algorithm = { name: 'AES-GCM', length }\n      keyUsages = ['encrypt', 'decrypt']\n      break\n    default:\n      throw new JOSENotSupported('Invalid or unsupported JWK \"alg\" (Algorithm) Parameter value')\n  }\n\n  return crypto.subtle.generateKey(algorithm, options?.extractable ?? false, keyUsages)\n}\n"
  },
  {
    "path": "src/key/import.ts",
    "content": "/**\n * Cryptographic key import functions\n *\n * @module\n */\n\nimport { decode as decodeBase64URL } from '../util/base64url.js'\nimport { fromSPKI, fromPKCS8, fromX509 } from '../lib/asn1.js'\nimport { jwkToKey } from '../lib/jwk_to_key.js'\n\nimport { JOSENotSupported } from '../util/errors.js'\nimport { isObject } from '../lib/type_checks.js'\nimport type * as types from '../types.d.ts'\n\n/** Key Import Function options. */\nexport interface KeyImportOptions {\n  /**\n   * The value to use as {@link !SubtleCrypto.importKey} `extractable` argument. Default is false for\n   * private keys, true otherwise.\n   */\n  extractable?: boolean\n}\n\n/**\n * Imports a PEM-encoded SPKI string as a {@link !CryptoKey}.\n *\n * > [!NOTE]\\\n * > The OID id-RSASSA-PSS (1.2.840.113549.1.1.10) is not supported in\n * > {@link https://w3c.github.io/webcrypto/ Web Cryptography API}, use the OID rsaEncryption\n * > (1.2.840.113549.1.1.1) instead for all RSA algorithms.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/key/import'`.\n *\n * @example\n *\n * ```js\n * const algorithm = 'ES256'\n * const spki = `-----BEGIN PUBLIC KEY-----\n * MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFlHHWfLk0gLBbsLTcuCrbCqoHqmM\n * YJepMC+Q+Dd6RBmBiA41evUsNMwLeN+PNFqib+xwi9JkJ8qhZkq8Y/IzGg==\n * -----END PUBLIC KEY-----`\n * const ecPublicKey = await jose.importSPKI(spki, algorithm)\n * ```\n *\n * @param spki PEM-encoded SPKI string\n * @param alg JSON Web Algorithm identifier to be used with the imported key. See\n *   {@link https://github.com/panva/jose/issues/210 Algorithm Key Requirements}.\n */\nexport async function importSPKI(\n  spki: string,\n  alg: string,\n  options?: KeyImportOptions,\n): Promise<types.CryptoKey> {\n  if (typeof spki !== 'string' || spki.indexOf('-----BEGIN PUBLIC KEY-----') !== 0) {\n    throw new TypeError('\"spki\" must be SPKI formatted string')\n  }\n  return fromSPKI(spki, alg, options)\n}\n\n/**\n * Imports the SPKI from an X.509 string certificate as a {@link !CryptoKey}.\n *\n * > [!NOTE]\\\n * > The OID id-RSASSA-PSS (1.2.840.113549.1.1.10) is not supported in\n * > {@link https://w3c.github.io/webcrypto/ Web Cryptography API}, use the OID rsaEncryption\n * > (1.2.840.113549.1.1.1) instead for all RSA algorithms.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/key/import'`.\n *\n * @example\n *\n * ```js\n * const algorithm = 'ES256'\n * const x509 = `-----BEGIN CERTIFICATE-----\n * MIIBXjCCAQSgAwIBAgIGAXvykuMKMAoGCCqGSM49BAMCMDYxNDAyBgNVBAMMK3Np\n * QXBNOXpBdk1VaXhXVWVGaGtjZXg1NjJRRzFyQUhXaV96UlFQTVpQaG8wHhcNMjEw\n * OTE3MDcwNTE3WhcNMjIwNzE0MDcwNTE3WjA2MTQwMgYDVQQDDCtzaUFwTTl6QXZN\n * VWl4V1VlRmhrY2V4NTYyUUcxckFIV2lfelJRUE1aUGhvMFkwEwYHKoZIzj0CAQYI\n * KoZIzj0DAQcDQgAE8PbPvCv5D5xBFHEZlBp/q5OEUymq7RIgWIi7tkl9aGSpYE35\n * UH+kBKDnphJO3odpPZ5gvgKs2nwRWcrDnUjYLDAKBggqhkjOPQQDAgNIADBFAiEA\n * 1yyMTRe66MhEXID9+uVub7woMkNYd0LhSHwKSPMUUTkCIFQGsfm1ecXOpeGOufAh\n * v+A1QWZMuTWqYt+uh/YSRNDn\n * -----END CERTIFICATE-----`\n * const ecPublicKey = await jose.importX509(x509, algorithm)\n * ```\n *\n * @param x509 X.509 certificate string\n * @param alg JSON Web Algorithm identifier to be used with the imported key. See\n *   {@link https://github.com/panva/jose/issues/210 Algorithm Key Requirements}.\n */\nexport async function importX509(\n  x509: string,\n  alg: string,\n  options?: KeyImportOptions,\n): Promise<types.CryptoKey> {\n  if (typeof x509 !== 'string' || x509.indexOf('-----BEGIN CERTIFICATE-----') !== 0) {\n    throw new TypeError('\"x509\" must be X.509 formatted string')\n  }\n  return fromX509(x509, alg, options)\n}\n\n/**\n * Imports a PEM-encoded PKCS#8 string as a {@link !CryptoKey}.\n *\n * > [!NOTE]\\\n * > The OID id-RSASSA-PSS (1.2.840.113549.1.1.10) is not supported in\n * > {@link https://w3c.github.io/webcrypto/ Web Cryptography API}, use the OID rsaEncryption\n * > (1.2.840.113549.1.1.1) instead for all RSA algorithms.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/key/import'`.\n *\n * @example\n *\n * ```js\n * const algorithm = 'ES256'\n * const pkcs8 = `-----BEGIN PRIVATE KEY-----\n * MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgiyvo0X+VQ0yIrOaN\n * nlrnUclopnvuuMfoc8HHly3505OhRANCAAQWUcdZ8uTSAsFuwtNy4KtsKqgeqYxg\n * l6kwL5D4N3pEGYGIDjV69Sw0zAt43480WqJv7HCL0mQnyqFmSrxj8jMa\n * -----END PRIVATE KEY-----`\n * const ecPrivateKey = await jose.importPKCS8(pkcs8, algorithm)\n * ```\n *\n * @param pkcs8 PEM-encoded PKCS#8 string\n * @param alg JSON Web Algorithm identifier to be used with the imported key. See\n *   {@link https://github.com/panva/jose/issues/210 Algorithm Key Requirements}.\n */\nexport async function importPKCS8(\n  pkcs8: string,\n  alg: string,\n  options?: KeyImportOptions,\n): Promise<types.CryptoKey> {\n  if (typeof pkcs8 !== 'string' || pkcs8.indexOf('-----BEGIN PRIVATE KEY-----') !== 0) {\n    throw new TypeError('\"pkcs8\" must be PKCS#8 formatted string')\n  }\n  return fromPKCS8(pkcs8, alg, options)\n}\n\n/**\n * Imports a JWK to a {@link !CryptoKey}. Either the JWK \"alg\" (Algorithm) Parameter, or the optional\n * \"alg\" argument, must be present for asymmetric JSON Web Key imports.\n *\n * > [!NOTE]\\\n * > The JSON Web Key parameters \"use\", \"key_ops\", and \"ext\" are also used in the {@link !CryptoKey}\n * > import process.\n *\n * > [!NOTE]\\\n * > Symmetric JSON Web Keys (i.e. `kty: \"oct\"`) yield back an {@link !Uint8Array} instead of a\n * > {@link !CryptoKey}.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/key/import'`.\n *\n * @example\n *\n * ```js\n * const ecPublicKey = await jose.importJWK(\n *   {\n *     crv: 'P-256',\n *     kty: 'EC',\n *     x: 'ySK38C1jBdLwDsNWKzzBHqKYEE5Cgv-qjWvorUXk9fw',\n *     y: '_LeQBw07cf5t57Iavn4j-BqJsAD1dpoz8gokd3sBsOo',\n *   },\n *   'ES256',\n * )\n *\n * const rsaPublicKey = await jose.importJWK(\n *   {\n *     kty: 'RSA',\n *     e: 'AQAB',\n *     n: '12oBZRhCiZFJLcPg59LkZZ9mdhSMTKAQZYq32k_ti5SBB6jerkh-WzOMAO664r_qyLkqHUSp3u5SbXtseZEpN3XPWGKSxjsy-1JyEFTdLSYe6f9gfrmxkUF_7DTpq0gn6rntP05g2-wFW50YO7mosfdslfrTJYWHFhJALabAeYirYD7-9kqq9ebfFMF4sRRELbv9oi36As6Q9B3Qb5_C1rAzqfao_PCsf9EPsTZsVVVkA5qoIAr47lo1ipfiBPxUCCNSdvkmDTYgvvRm6ZoMjFbvOtgyts55fXKdMWv7I9HMD5HwE9uW839PWA514qhbcIsXEYSFMPMV6fnlsiZvQQ',\n *   },\n *   'PS256',\n * )\n * ```\n *\n * @param jwk JSON Web Key.\n * @param alg JSON Web Algorithm identifier to be used with the imported key. Default is the \"alg\"\n *   property on the JWK. See\n *   {@link https://github.com/panva/jose/issues/210 Algorithm Key Requirements}.\n */\nexport async function importJWK(\n  jwk: types.JWK,\n  alg?: string,\n  options?: KeyImportOptions,\n): Promise<types.CryptoKey | Uint8Array> {\n  if (!isObject(jwk)) {\n    throw new TypeError('JWK must be an object')\n  }\n\n  let ext: boolean | undefined\n\n  alg ??= jwk.alg\n  ext ??= options?.extractable ?? jwk.ext\n\n  switch (jwk.kty) {\n    case 'oct':\n      if (typeof jwk.k !== 'string' || !jwk.k) {\n        throw new TypeError('missing \"k\" (Key Value) Parameter value')\n      }\n\n      return decodeBase64URL(jwk.k)\n    case 'RSA':\n      if ('oth' in jwk && jwk.oth !== undefined) {\n        throw new JOSENotSupported(\n          'RSA JWK \"oth\" (Other Primes Info) Parameter value is not supported',\n        )\n      }\n      return jwkToKey({ ...jwk, alg, ext })\n    case 'AKP': {\n      if (typeof jwk.alg !== 'string' || !jwk.alg) {\n        throw new TypeError('missing \"alg\" (Algorithm) Parameter value')\n      }\n      if (alg !== undefined && alg !== jwk.alg) {\n        throw new TypeError('JWK alg and alg option value mismatch')\n      }\n      return jwkToKey({ ...jwk, ext })\n    }\n    case 'EC':\n    case 'OKP':\n      return jwkToKey({ ...jwk, alg, ext })\n    default:\n      throw new JOSENotSupported('Unsupported \"kty\" (Key Type) Parameter value')\n  }\n}\n"
  },
  {
    "path": "src/lib/aesgcmkw.ts",
    "content": "import { encrypt, decrypt } from './content_encryption.js'\nimport { encode as b64u } from '../util/base64url.js'\n\nexport async function wrap(alg: string, key: unknown, cek: Uint8Array, iv?: Uint8Array) {\n  const jweAlgorithm = alg.slice(0, 7)\n\n  const wrapped = await encrypt(jweAlgorithm, cek, key, iv, new Uint8Array())\n\n  return {\n    encryptedKey: wrapped.ciphertext,\n    iv: b64u(wrapped.iv!),\n    tag: b64u(wrapped.tag!),\n  }\n}\n\nexport async function unwrap(\n  alg: string,\n  key: unknown,\n  encryptedKey: Uint8Array,\n  iv: Uint8Array,\n  tag: Uint8Array,\n) {\n  const jweAlgorithm = alg.slice(0, 7)\n  return decrypt(jweAlgorithm, key, encryptedKey, iv, tag, new Uint8Array())\n}\n"
  },
  {
    "path": "src/lib/aeskw.ts",
    "content": "import type * as types from '../types.d.ts'\nimport { checkEncCryptoKey } from './crypto_key.js'\n\nfunction checkKeySize(key: types.CryptoKey, alg: string) {\n  if ((key.algorithm as AesKeyAlgorithm).length !== parseInt(alg.slice(1, 4), 10)) {\n    throw new TypeError(`Invalid key size for alg: ${alg}`)\n  }\n}\n\nfunction getCryptoKey(key: types.CryptoKey | Uint8Array, alg: string, usage: KeyUsage) {\n  if (key instanceof Uint8Array) {\n    return crypto.subtle.importKey('raw', key as Uint8Array<ArrayBuffer>, 'AES-KW', true, [usage])\n  }\n  checkEncCryptoKey(key, alg, usage)\n  return key\n}\n\nexport async function wrap(alg: string, key: types.CryptoKey | Uint8Array, cek: Uint8Array) {\n  const cryptoKey = await getCryptoKey(key, alg, 'wrapKey')\n\n  checkKeySize(cryptoKey, alg)\n\n  // algorithm used is irrelevant\n  const cryptoKeyCek = await crypto.subtle.importKey(\n    'raw',\n    cek as Uint8Array<ArrayBuffer>,\n    { hash: 'SHA-256', name: 'HMAC' },\n    true,\n    ['sign'],\n  )\n\n  return new Uint8Array(await crypto.subtle.wrapKey('raw', cryptoKeyCek, cryptoKey, 'AES-KW'))\n}\n\nexport async function unwrap(\n  alg: string,\n  key: types.CryptoKey | Uint8Array,\n  encryptedKey: Uint8Array,\n) {\n  const cryptoKey = await getCryptoKey(key, alg, 'unwrapKey')\n\n  checkKeySize(cryptoKey, alg)\n\n  // algorithm used is irrelevant\n  const cryptoKeyCek = await crypto.subtle.unwrapKey(\n    'raw',\n    encryptedKey as Uint8Array<ArrayBuffer>,\n    cryptoKey,\n    'AES-KW',\n    { hash: 'SHA-256', name: 'HMAC' },\n    true,\n    ['sign'],\n  )\n\n  return new Uint8Array(await crypto.subtle.exportKey('raw', cryptoKeyCek))\n}\n"
  },
  {
    "path": "src/lib/asn1.ts",
    "content": "import type * as types from '../types.d.ts'\nimport { invalidKeyInput } from './invalid_key_input.js'\nimport { encodeBase64, decodeBase64 } from '../lib/base64.js'\nimport { JOSENotSupported } from '../util/errors.js'\nimport { isCryptoKey, isKeyObject } from './is_key_like.js'\n\nimport type { KeyImportOptions } from '../key/import.js'\n\n/**\n * Formats a base64 string as a PEM-encoded key with proper line breaks and headers.\n *\n * @param b64 - Base64-encoded key data\n * @param descriptor - Key type descriptor (e.g., \"PUBLIC KEY\", \"PRIVATE KEY\")\n *\n * @returns PEM-formatted string\n */\nconst formatPEM = (b64: string, descriptor: string) => {\n  const newlined = (b64.match(/.{1,64}/g) || []).join('\\n')\n  return `-----BEGIN ${descriptor}-----\\n${newlined}\\n-----END ${descriptor}-----`\n}\n\ninterface ExportOptions {\n  format: 'pem'\n  type: 'spki' | 'pkcs8'\n}\n\ninterface ExtractableKeyObject extends types.KeyObject {\n  export(arg: ExportOptions): string\n}\n\nconst genericExport = async (\n  keyType: 'private' | 'public',\n  keyFormat: 'spki' | 'pkcs8',\n  key: unknown,\n) => {\n  if (isKeyObject(key)) {\n    if (key.type !== keyType) {\n      throw new TypeError(`key is not a ${keyType} key`)\n    }\n\n    return (key as ExtractableKeyObject).export({ format: 'pem', type: keyFormat })\n  }\n\n  if (!isCryptoKey(key)) {\n    throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'KeyObject'))\n  }\n\n  if (!key.extractable) {\n    throw new TypeError('CryptoKey is not extractable')\n  }\n\n  if (key.type !== keyType) {\n    throw new TypeError(`key is not a ${keyType} key`)\n  }\n\n  return formatPEM(\n    encodeBase64(new Uint8Array(await crypto.subtle.exportKey(keyFormat, key))),\n    `${keyType.toUpperCase()} KEY`,\n  )\n}\n\nexport const toSPKI = (key: unknown): Promise<string> => genericExport('public', 'spki', key)\n\nexport const toPKCS8 = (key: unknown): Promise<string> => genericExport('private', 'pkcs8', key)\n\n/** Helper function to compare two byte arrays for equality */\nconst bytesEqual = (a: Uint8Array, b: readonly number[]): boolean => {\n  if (a.byteLength !== b.length) return false\n  for (let i = 0; i < a.byteLength; i++) {\n    if (a[i] !== b[i]) return false\n  }\n  return true\n}\n\n/** ASN.1 DER parsing state */\ninterface ASN1State {\n  readonly data: Uint8Array\n  pos: number\n}\n\n/** Creates ASN.1 parsing state */\nconst createASN1State = (data: Uint8Array): ASN1State => ({ data, pos: 0 })\n\n/** Parses ASN.1 length encoding (both short and long form) */\nconst parseLength = (state: ASN1State): number => {\n  const first = state.data[state.pos++]\n  if (first & 0x80) {\n    // Long form: first byte indicates number of subsequent length bytes\n    const lengthOfLen = first & 0x7f\n    let length = 0\n    for (let i = 0; i < lengthOfLen; i++) {\n      length = (length << 8) | state.data[state.pos++]\n    }\n    return length\n  }\n  // Short form: length is encoded directly in first byte\n  return first\n}\n\n/** Skips ASN.1 elements (tag + length + content) */\nconst skipElement = (state: ASN1State, count: number = 1): void => {\n  if (count <= 0) return\n  state.pos++ // Skip tag byte\n  const length = parseLength(state)\n  state.pos += length // Skip content bytes\n  if (count > 1) {\n    skipElement(state, count - 1) // Recursively skip remaining elements\n  }\n}\n\n/** Expects a specific tag and throws if not found */\nconst expectTag = (state: ASN1State, expectedTag: number, errorMessage: string): void => {\n  if (state.data[state.pos++] !== expectedTag) {\n    throw new Error(errorMessage)\n  }\n}\n\n/** Gets a subarray from current position */\nconst getSubarray = (state: ASN1State, length: number): Uint8Array => {\n  const result = state.data.subarray(state.pos, state.pos + length)\n  state.pos += length\n  return result\n}\n\n/** Parses algorithm OID and returns the OID bytes */\nconst parseAlgorithmOID = (state: ASN1State): Uint8Array => {\n  expectTag(state, 0x06, 'Expected algorithm OID')\n  const oidLen = parseLength(state)\n  return getSubarray(state, oidLen)\n}\n\n/** Parses a PKCS#8 private key structure up to the privateKey field */\nfunction parsePKCS8Header(state: ASN1State) {\n  // Parse outer SEQUENCE (PrivateKeyInfo)\n  expectTag(state, 0x30, 'Invalid PKCS#8 structure')\n  parseLength(state) // Skip outer length\n\n  // Skip version (INTEGER)\n  expectTag(state, 0x02, 'Expected version field')\n  const verLen = parseLength(state)\n  state.pos += verLen\n\n  // Parse privateKeyAlgorithm (AlgorithmIdentifier SEQUENCE)\n  expectTag(state, 0x30, 'Expected algorithm identifier')\n  const algIdLen = parseLength(state)\n  const algIdStart = state.pos\n\n  return { algIdStart, algIdLength: algIdLen }\n}\n\n/** Parses an SPKI structure up to the subjectPublicKey field */\nfunction parseSPKIHeader(state: ASN1State) {\n  // Parse outer SEQUENCE (SubjectPublicKeyInfo)\n  expectTag(state, 0x30, 'Invalid SPKI structure')\n  parseLength(state) // Skip outer length\n\n  // Parse algorithm identifier (AlgorithmIdentifier SEQUENCE)\n  expectTag(state, 0x30, 'Expected algorithm identifier')\n  const algIdLen = parseLength(state)\n  const algIdStart = state.pos\n\n  return { algIdStart, algIdLength: algIdLen }\n}\n\n/** Parses algorithm identifier and returns curve name for EC/ECDH keys */\nconst parseECAlgorithmIdentifier = (state: ASN1State): string => {\n  const algOid = parseAlgorithmOID(state)\n\n  // id-x25519\n  if (bytesEqual(algOid, [0x2b, 0x65, 0x6e])) {\n    return 'X25519'\n  }\n\n  // id-ecPublicKey 1.2.840.10045.2.1\n  if (!bytesEqual(algOid, [0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01])) {\n    throw new Error('Unsupported key algorithm')\n  }\n\n  // Parse curve parameters (should be an OID for named curves)\n  expectTag(state, 0x06, 'Expected curve OID')\n  const curveOidLen = parseLength(state)\n  const curveOid = getSubarray(state, curveOidLen)\n\n  // Compare with known curve OIDs - NIST curves inlined\n  for (const { name, oid } of [\n    { name: 'P-256', oid: [0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07] }, // 1.2.840.10045.3.1.7\n    { name: 'P-384', oid: [0x2b, 0x81, 0x04, 0x00, 0x22] }, // 1.3.132.0.34\n    { name: 'P-521', oid: [0x2b, 0x81, 0x04, 0x00, 0x23] }, // 1.3.132.0.35\n  ] as const) {\n    if (bytesEqual(curveOid, oid)) {\n      return name\n    }\n  }\n\n  throw new Error('Unsupported named curve')\n}\n\nconst genericImport = async (\n  keyFormat: 'spki' | 'pkcs8',\n  keyData: Uint8Array,\n  alg: string,\n  options?: KeyImportOptions & { getNamedCurve?: (keyData: Uint8Array) => string },\n) => {\n  let algorithm: RsaHashedImportParams | EcKeyAlgorithm | Algorithm\n  let keyUsages: KeyUsage[]\n\n  const isPublic = keyFormat === 'spki'\n\n  // Helper functions for determining key usage based on key type\n  const getSigUsages = (): KeyUsage[] => (isPublic ? ['verify'] : ['sign'])\n  const getEncUsages = (): KeyUsage[] =>\n    isPublic ? ['encrypt', 'wrapKey'] : ['decrypt', 'unwrapKey']\n\n  switch (alg) {\n    case 'PS256':\n    case 'PS384':\n    case 'PS512':\n      algorithm = { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` }\n      keyUsages = getSigUsages()\n      break\n    case 'RS256':\n    case 'RS384':\n    case 'RS512':\n      algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` }\n      keyUsages = getSigUsages()\n      break\n    case 'RSA-OAEP':\n    case 'RSA-OAEP-256':\n    case 'RSA-OAEP-384':\n    case 'RSA-OAEP-512':\n      algorithm = {\n        name: 'RSA-OAEP',\n        hash: `SHA-${parseInt(alg.slice(-3), 10) || 1}`,\n      }\n      keyUsages = getEncUsages()\n      break\n    case 'ES256':\n    case 'ES384':\n    case 'ES512': {\n      const curveMap = { ES256: 'P-256', ES384: 'P-384', ES512: 'P-521' } as const\n      algorithm = { name: 'ECDSA', namedCurve: curveMap[alg] }\n      keyUsages = getSigUsages()\n      break\n    }\n    case 'ECDH-ES':\n    case 'ECDH-ES+A128KW':\n    case 'ECDH-ES+A192KW':\n    case 'ECDH-ES+A256KW': {\n      try {\n        const namedCurve = options!.getNamedCurve!(keyData)\n        algorithm = namedCurve === 'X25519' ? { name: 'X25519' } : { name: 'ECDH', namedCurve }\n      } catch (cause) {\n        throw new JOSENotSupported('Invalid or unsupported key format')\n      }\n      keyUsages = isPublic ? [] : ['deriveBits']\n      break\n    }\n    case 'Ed25519':\n    case 'EdDSA':\n      algorithm = { name: 'Ed25519' }\n      keyUsages = getSigUsages()\n      break\n    case 'ML-DSA-44':\n    case 'ML-DSA-65':\n    case 'ML-DSA-87':\n      algorithm = { name: alg }\n      keyUsages = getSigUsages()\n      break\n    default:\n      throw new JOSENotSupported('Invalid or unsupported \"alg\" (Algorithm) value')\n  }\n\n  return crypto.subtle.importKey(\n    keyFormat,\n    keyData as Uint8Array<ArrayBuffer>,\n    algorithm,\n    options?.extractable ?? (isPublic ? true : false),\n    keyUsages,\n  )\n}\n\ntype PEMImportFunction = (\n  pem: string,\n  alg: string,\n  options?: KeyImportOptions,\n) => Promise<types.CryptoKey>\n\n/** Helper function to process PEM-encoded data */\nconst processPEMData = (pem: string, pattern: RegExp): Uint8Array => {\n  return decodeBase64(pem.replace(pattern, ''))\n}\n\nexport const fromPKCS8: PEMImportFunction = (pem, alg, options?) => {\n  const keyData = processPEMData(pem, /(?:-----(?:BEGIN|END) PRIVATE KEY-----|\\s)/g)\n\n  let opts: Parameters<typeof genericImport>[3] = options\n\n  if (alg?.startsWith?.('ECDH-ES')) {\n    opts ||= {}\n    opts.getNamedCurve = (keyData: Uint8Array) => {\n      const state = createASN1State(keyData)\n      parsePKCS8Header(state)\n      return parseECAlgorithmIdentifier(state)\n    }\n  }\n\n  return genericImport('pkcs8', keyData, alg, opts)\n}\n\nexport const fromSPKI: PEMImportFunction = (pem, alg, options?) => {\n  const keyData = processPEMData(pem, /(?:-----(?:BEGIN|END) PUBLIC KEY-----|\\s)/g)\n\n  let opts: Parameters<typeof genericImport>[3] = options\n\n  if (alg?.startsWith?.('ECDH-ES')) {\n    opts ||= {}\n    opts.getNamedCurve = (keyData: Uint8Array) => {\n      const state = createASN1State(keyData)\n      parseSPKIHeader(state)\n      return parseECAlgorithmIdentifier(state)\n    }\n  }\n\n  return genericImport('spki', keyData, alg, opts)\n}\n\n/**\n * Extracts the Subject Public Key Info (SPKI) from an X.509 certificate. Parses the ASN.1 DER\n * structure to locate and extract the public key portion.\n *\n * @param buf - DER-encoded X.509 certificate bytes\n *\n * @returns SPKI structure as bytes\n */\nfunction spkiFromX509(buf: Uint8Array): Uint8Array {\n  const state = createASN1State(buf)\n\n  // Parse outer certificate SEQUENCE\n  expectTag(state, 0x30, 'Invalid certificate structure')\n  parseLength(state) // Skip certificate length\n\n  // Parse tbsCertificate (To Be Signed Certificate) SEQUENCE\n  expectTag(state, 0x30, 'Invalid tbsCertificate structure')\n  parseLength(state) // Skip tbsCertificate length\n\n  if (buf[state.pos] === 0xa0) {\n    // Optional version field present (context-specific [0])\n    // Skip: version, serialNumber, signature algorithm, issuer, validity, subject\n    skipElement(state, 6)\n  } else {\n    // No version field (defaults to v1)\n    // Skip: serialNumber, signature algorithm, issuer, validity, subject\n    skipElement(state, 5)\n  }\n\n  // Extract subjectPublicKeyInfo SEQUENCE\n  const spkiStart = state.pos\n  expectTag(state, 0x30, 'Invalid SPKI structure')\n  const spkiContentLen = parseLength(state)\n\n  // Return the complete SPKI structure (tag + length + content)\n  return buf.subarray(spkiStart, spkiStart + spkiContentLen + (state.pos - spkiStart))\n}\n\n/**\n * Extracts SPKI from a PEM-encoded X.509 certificate string.\n *\n * @param x509 - PEM-encoded X.509 certificate\n *\n * @returns SPKI structure as bytes\n */\nfunction extractX509SPKI(x509: string): Uint8Array {\n  const derBytes = processPEMData(x509, /(?:-----(?:BEGIN|END) CERTIFICATE-----|\\s)/g)\n  return spkiFromX509(derBytes)\n}\n\nexport const fromX509: PEMImportFunction = (pem, alg, options?) => {\n  let spki: Uint8Array\n  try {\n    spki = extractX509SPKI(pem)\n  } catch (cause) {\n    throw new TypeError('Failed to parse the X.509 certificate', { cause })\n  }\n  return fromSPKI(formatPEM(encodeBase64(spki), 'PUBLIC KEY'), alg, options)\n}\n"
  },
  {
    "path": "src/lib/base64.ts",
    "content": "export function encodeBase64(input: Uint8Array): string {\n  // @ts-ignore\n  if (Uint8Array.prototype.toBase64) {\n    // @ts-ignore\n    return input.toBase64()\n  }\n\n  const CHUNK_SIZE = 0x8000\n  const arr = []\n  for (let i = 0; i < input.length; i += CHUNK_SIZE) {\n    // @ts-ignore\n    arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)))\n  }\n  return btoa(arr.join(''))\n}\n\nexport function decodeBase64(encoded: string): Uint8Array {\n  // @ts-ignore\n  if (Uint8Array.fromBase64) {\n    // @ts-ignore\n    return Uint8Array.fromBase64(encoded)\n  }\n\n  const binary = atob(encoded)\n  const bytes = new Uint8Array(binary.length)\n  for (let i = 0; i < binary.length; i++) {\n    bytes[i] = binary.charCodeAt(i)\n  }\n  return bytes\n}\n"
  },
  {
    "path": "src/lib/buffer_utils.ts",
    "content": "export const encoder = new TextEncoder()\nexport const decoder = new TextDecoder()\n\nconst MAX_INT32 = 2 ** 32\n\nexport function concat(...buffers: Uint8Array[]): Uint8Array {\n  const size = buffers.reduce((acc, { length }) => acc + length, 0)\n  const buf = new Uint8Array(size)\n  let i = 0\n  for (const buffer of buffers) {\n    buf.set(buffer, i)\n    i += buffer.length\n  }\n  return buf\n}\n\nfunction writeUInt32BE(buf: Uint8Array, value: number, offset?: number) {\n  if (value < 0 || value >= MAX_INT32) {\n    throw new RangeError(`value must be >= 0 and <= ${MAX_INT32 - 1}. Received ${value}`)\n  }\n  buf.set([value >>> 24, value >>> 16, value >>> 8, value & 0xff], offset)\n}\n\nexport function uint64be(value: number) {\n  const high = Math.floor(value / MAX_INT32)\n  const low = value % MAX_INT32\n  const buf = new Uint8Array(8)\n  writeUInt32BE(buf, high, 0)\n  writeUInt32BE(buf, low, 4)\n  return buf\n}\n\nexport function uint32be(value: number) {\n  const buf = new Uint8Array(4)\n  writeUInt32BE(buf, value)\n  return buf\n}\n\n/** Encodes ASCII-only strings as Uint8Array */\nexport function encode(string: string): Uint8Array {\n  const bytes = new Uint8Array(string.length)\n  for (let i = 0; i < string.length; i++) {\n    const code = string.charCodeAt(i)\n    if (code > 127) {\n      throw new TypeError('non-ASCII string encountered in encode()')\n    }\n    bytes[i] = code\n  }\n  return bytes\n}\n"
  },
  {
    "path": "src/lib/check_key_type.ts",
    "content": "import { withAlg as invalidKeyInput } from './invalid_key_input.js'\nimport { isKeyLike } from './is_key_like.js'\nimport * as jwk from './type_checks.js'\nimport type * as types from '../types.d.ts'\n\n// @ts-ignore\nconst tag = (key: unknown): string => key?.[Symbol.toStringTag]\n\nconst jwkMatchesOp = (alg: string, key: types.JWK, usage: Usage) => {\n  if (key.use !== undefined) {\n    let expected: string\n    switch (usage) {\n      case 'sign':\n      case 'verify':\n        expected = 'sig'\n        break\n      case 'encrypt':\n      case 'decrypt':\n        expected = 'enc'\n        break\n    }\n    if (key.use !== expected) {\n      throw new TypeError(\n        `Invalid key for this operation, its \"use\" must be \"${expected}\" when present`,\n      )\n    }\n  }\n\n  if (key.alg !== undefined && key.alg !== alg) {\n    throw new TypeError(`Invalid key for this operation, its \"alg\" must be \"${alg}\" when present`)\n  }\n\n  if (Array.isArray(key.key_ops)) {\n    let expectedKeyOp\n\n    switch (true) {\n      case usage === 'sign' || usage === 'verify': // Fall through\n      case alg === 'dir': // Fall through\n      case alg.includes('CBC-HS'):\n        expectedKeyOp = usage\n        break\n      case alg.startsWith('PBES2'):\n        expectedKeyOp = 'deriveBits'\n        break\n      case /^A\\d{3}(?:GCM)?(?:KW)?$/.test(alg):\n        if (!alg.includes('GCM') && alg.endsWith('KW')) {\n          expectedKeyOp = usage === 'encrypt' ? 'wrapKey' : 'unwrapKey'\n        } else {\n          expectedKeyOp = usage\n        }\n        break\n      case usage === 'encrypt' && alg.startsWith('RSA'):\n        expectedKeyOp = 'wrapKey'\n        break\n      case usage === 'decrypt':\n        expectedKeyOp = alg.startsWith('RSA') ? 'unwrapKey' : 'deriveBits'\n        break\n    }\n\n    if (expectedKeyOp && key.key_ops?.includes?.(expectedKeyOp) === false) {\n      throw new TypeError(\n        `Invalid key for this operation, its \"key_ops\" must include \"${expectedKeyOp}\" when present`,\n      )\n    }\n  }\n\n  return true\n}\n\nconst symmetricTypeCheck = (alg: string, key: unknown, usage: Usage) => {\n  if (key instanceof Uint8Array) return\n\n  if (jwk.isJWK(key)) {\n    if (jwk.isSecretJWK(key) && jwkMatchesOp(alg, key, usage)) return\n    throw new TypeError(\n      `JSON Web Key for symmetric algorithms must have JWK \"kty\" (Key Type) equal to \"oct\" and the JWK \"k\" (Key Value) present`,\n    )\n  }\n\n  if (!isKeyLike(key)) {\n    throw new TypeError(\n      invalidKeyInput(alg, key, 'CryptoKey', 'KeyObject', 'JSON Web Key', 'Uint8Array'),\n    )\n  }\n\n  if (key.type !== 'secret') {\n    throw new TypeError(`${tag(key)} instances for symmetric algorithms must be of type \"secret\"`)\n  }\n}\n\nconst asymmetricTypeCheck = (alg: string, key: unknown, usage: Usage) => {\n  if (jwk.isJWK(key)) {\n    switch (usage) {\n      case 'decrypt':\n      case 'sign':\n        if (jwk.isPrivateJWK(key) && jwkMatchesOp(alg, key, usage)) return\n        throw new TypeError(`JSON Web Key for this operation must be a private JWK`)\n      case 'encrypt':\n      case 'verify':\n        if (jwk.isPublicJWK(key) && jwkMatchesOp(alg, key, usage)) return\n        throw new TypeError(`JSON Web Key for this operation must be a public JWK`)\n    }\n  }\n\n  if (!isKeyLike(key)) {\n    throw new TypeError(invalidKeyInput(alg, key, 'CryptoKey', 'KeyObject', 'JSON Web Key'))\n  }\n\n  if (key.type === 'secret') {\n    throw new TypeError(\n      `${tag(key)} instances for asymmetric algorithms must not be of type \"secret\"`,\n    )\n  }\n\n  if (key.type === 'public') {\n    switch (usage) {\n      case 'sign':\n        throw new TypeError(\n          `${tag(key)} instances for asymmetric algorithm signing must be of type \"private\"`,\n        )\n      case 'decrypt':\n        throw new TypeError(\n          `${tag(key)} instances for asymmetric algorithm decryption must be of type \"private\"`,\n        )\n    }\n  }\n\n  if (key.type === 'private') {\n    switch (usage) {\n      case 'verify':\n        throw new TypeError(\n          `${tag(key)} instances for asymmetric algorithm verifying must be of type \"public\"`,\n        )\n      case 'encrypt':\n        throw new TypeError(\n          `${tag(key)} instances for asymmetric algorithm encryption must be of type \"public\"`,\n        )\n    }\n  }\n}\n\ntype Usage = 'sign' | 'verify' | 'encrypt' | 'decrypt'\n\nexport function checkKeyType(alg: string, key: unknown, usage: Usage): void {\n  switch (alg.substring(0, 2)) {\n    case 'A1': // A128.+, A192.+\n    case 'A2': // A256.+\n    case 'di': // dir\n    case 'HS': // HS\\d{3}\n    case 'PB': // PBES2.+\n      symmetricTypeCheck(alg, key, usage)\n      break\n    default:\n      asymmetricTypeCheck(alg, key, usage)\n  }\n}\n"
  },
  {
    "path": "src/lib/content_encryption.ts",
    "content": "import type * as types from '../types.d.ts'\nimport { concat, uint64be } from './buffer_utils.js'\nimport { checkEncCryptoKey } from './crypto_key.js'\nimport { invalidKeyInput } from './invalid_key_input.js'\nimport { JOSENotSupported, JWEDecryptionFailed, JWEInvalid } from '../util/errors.js'\nimport { isCryptoKey } from './is_key_like.js'\n\n// --- CEK ---\n\nexport function cekLength(alg: string) {\n  switch (alg) {\n    case 'A128GCM':\n      return 128\n    case 'A192GCM':\n      return 192\n    case 'A256GCM':\n    case 'A128CBC-HS256':\n      return 256\n    case 'A192CBC-HS384':\n      return 384\n    case 'A256CBC-HS512':\n      return 512\n    default:\n      throw new JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`)\n  }\n}\n\nexport const generateCek = (alg: string): Uint8Array =>\n  crypto.getRandomValues(new Uint8Array(cekLength(alg) >> 3))\n\nfunction checkCekLength(cek: Uint8Array, expected: number) {\n  const actual = cek.byteLength << 3\n  if (actual !== expected) {\n    throw new JWEInvalid(\n      `Invalid Content Encryption Key length. Expected ${expected} bits, got ${actual} bits`,\n    )\n  }\n}\n\n// --- IV ---\n\nfunction ivBitLength(alg: string) {\n  switch (alg) {\n    case 'A128GCM':\n    case 'A128GCMKW':\n    case 'A192GCM':\n    case 'A192GCMKW':\n    case 'A256GCM':\n    case 'A256GCMKW':\n      return 96\n    case 'A128CBC-HS256':\n    case 'A192CBC-HS384':\n    case 'A256CBC-HS512':\n      return 128\n    default:\n      throw new JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`)\n  }\n}\n\nexport const generateIv = (alg: string): Uint8Array =>\n  crypto.getRandomValues(new Uint8Array(ivBitLength(alg) >> 3))\n\nexport function checkIvLength(enc: string, iv: Uint8Array) {\n  if (iv.length << 3 !== ivBitLength(enc)) {\n    throw new JWEInvalid('Invalid Initialization Vector length')\n  }\n}\n\n// --- CBC helpers ---\n\nasync function cbcKeySetup(\n  enc: string,\n  cek: Uint8Array | types.CryptoKey,\n  usage: 'encrypt' | 'decrypt',\n): Promise<{ encKey: CryptoKey; macKey: CryptoKey; keySize: number }> {\n  if (!(cek instanceof Uint8Array)) {\n    throw new TypeError(invalidKeyInput(cek, 'Uint8Array'))\n  }\n  const keySize = parseInt(enc.slice(1, 4), 10)\n  const encKey = await crypto.subtle.importKey(\n    'raw',\n    cek.subarray(keySize >> 3) as Uint8Array<ArrayBuffer>,\n    'AES-CBC',\n    false,\n    [usage],\n  )\n  const macKey = await crypto.subtle.importKey(\n    'raw',\n    cek.subarray(0, keySize >> 3) as Uint8Array<ArrayBuffer>,\n    {\n      hash: `SHA-${keySize << 1}`,\n      name: 'HMAC',\n    },\n    false,\n    ['sign'],\n  )\n  return { encKey, macKey, keySize }\n}\n\nasync function cbcHmacTag(\n  macKey: CryptoKey,\n  macData: Uint8Array,\n  keySize: number,\n): Promise<Uint8Array> {\n  return new Uint8Array(\n    (await crypto.subtle.sign('HMAC', macKey, macData as Uint8Array<ArrayBuffer>)).slice(\n      0,\n      keySize >> 3,\n    ),\n  )\n}\n\n// --- CBC encrypt/decrypt ---\n\nasync function cbcEncrypt(\n  enc: string,\n  plaintext: Uint8Array,\n  cek: Uint8Array | types.CryptoKey,\n  iv: Uint8Array,\n  aad: Uint8Array,\n) {\n  const { encKey, macKey, keySize } = await cbcKeySetup(enc, cek, 'encrypt')\n\n  const ciphertext = new Uint8Array(\n    await crypto.subtle.encrypt(\n      {\n        iv: iv as Uint8Array<ArrayBuffer>,\n        name: 'AES-CBC',\n      },\n      encKey,\n      plaintext as Uint8Array<ArrayBuffer>,\n    ),\n  )\n\n  const macData = concat(aad, iv, ciphertext, uint64be(aad.length << 3))\n  const tag = await cbcHmacTag(macKey, macData, keySize)\n\n  return { ciphertext, tag, iv }\n}\n\nasync function timingSafeEqual(a: Uint8Array, b: Uint8Array): Promise<boolean> {\n  if (!(a instanceof Uint8Array)) {\n    throw new TypeError('First argument must be a buffer')\n  }\n  if (!(b instanceof Uint8Array)) {\n    throw new TypeError('Second argument must be a buffer')\n  }\n\n  const algorithm = { name: 'HMAC', hash: 'SHA-256' }\n  const key = (await crypto.subtle.generateKey(algorithm, false, ['sign'])) as CryptoKey\n\n  const aHmac = new Uint8Array(\n    await crypto.subtle.sign(algorithm, key, a as Uint8Array<ArrayBuffer>),\n  )\n  const bHmac = new Uint8Array(\n    await crypto.subtle.sign(algorithm, key, b as Uint8Array<ArrayBuffer>),\n  )\n\n  let out = 0\n  let i = -1\n  while (++i < 32) {\n    out |= aHmac[i] ^ bHmac[i]\n  }\n\n  return out === 0\n}\n\nasync function cbcDecrypt(\n  enc: string,\n  cek: Uint8Array | types.CryptoKey,\n  ciphertext: Uint8Array,\n  iv: Uint8Array,\n  tag: Uint8Array,\n  aad: Uint8Array,\n) {\n  const { encKey, macKey, keySize } = await cbcKeySetup(enc, cek, 'decrypt')\n\n  const macData = concat(aad, iv, ciphertext, uint64be(aad.length << 3))\n  const expectedTag = await cbcHmacTag(macKey, macData, keySize)\n\n  let macCheckPassed!: boolean\n  try {\n    macCheckPassed = await timingSafeEqual(tag, expectedTag)\n  } catch {\n    //\n  }\n  if (!macCheckPassed) {\n    throw new JWEDecryptionFailed()\n  }\n\n  let plaintext!: Uint8Array\n  try {\n    plaintext = new Uint8Array(\n      await crypto.subtle.decrypt(\n        { iv: iv as Uint8Array<ArrayBuffer>, name: 'AES-CBC' },\n        encKey,\n        ciphertext as Uint8Array<ArrayBuffer>,\n      ),\n    )\n  } catch {\n    //\n  }\n  if (!plaintext) {\n    throw new JWEDecryptionFailed()\n  }\n\n  return plaintext\n}\n\n// --- GCM encrypt/decrypt ---\n\nasync function gcmEncrypt(\n  enc: string,\n  plaintext: Uint8Array,\n  cek: Uint8Array | types.CryptoKey,\n  iv: Uint8Array,\n  aad: Uint8Array,\n) {\n  let encKey: types.CryptoKey\n  if (cek instanceof Uint8Array) {\n    encKey = await crypto.subtle.importKey(\n      'raw',\n      cek as Uint8Array<ArrayBuffer>,\n      'AES-GCM',\n      false,\n      ['encrypt'],\n    )\n  } else {\n    checkEncCryptoKey(cek, enc, 'encrypt')\n    encKey = cek\n  }\n\n  const encrypted = new Uint8Array(\n    await crypto.subtle.encrypt(\n      {\n        additionalData: aad as Uint8Array<ArrayBuffer>,\n        iv: iv as Uint8Array<ArrayBuffer>,\n        name: 'AES-GCM',\n        tagLength: 128,\n      },\n      encKey,\n      plaintext as Uint8Array<ArrayBuffer>,\n    ),\n  )\n\n  const tag = encrypted.slice(-16)\n  const ciphertext = encrypted.slice(0, -16)\n\n  return { ciphertext, tag, iv }\n}\n\nasync function gcmDecrypt(\n  enc: string,\n  cek: Uint8Array | types.CryptoKey,\n  ciphertext: Uint8Array,\n  iv: Uint8Array,\n  tag: Uint8Array,\n  aad: Uint8Array,\n) {\n  let encKey: types.CryptoKey\n  if (cek instanceof Uint8Array) {\n    encKey = await crypto.subtle.importKey(\n      'raw',\n      cek as Uint8Array<ArrayBuffer>,\n      'AES-GCM',\n      false,\n      ['decrypt'],\n    )\n  } else {\n    checkEncCryptoKey(cek, enc, 'decrypt')\n    encKey = cek\n  }\n\n  try {\n    return new Uint8Array(\n      await crypto.subtle.decrypt(\n        {\n          additionalData: aad as Uint8Array<ArrayBuffer>,\n          iv: iv as Uint8Array<ArrayBuffer>,\n          name: 'AES-GCM',\n          tagLength: 128,\n        },\n        encKey,\n        concat(ciphertext, tag) as Uint8Array<ArrayBuffer>,\n      ),\n    )\n  } catch {\n    throw new JWEDecryptionFailed()\n  }\n}\n\n// --- Public API ---\n\nconst unsupportedEnc = 'Unsupported JWE Content Encryption Algorithm'\n\nexport async function encrypt(\n  enc: string,\n  plaintext: Uint8Array,\n  cek: unknown,\n  iv: Uint8Array | undefined,\n  aad: Uint8Array,\n): Promise<{\n  ciphertext: Uint8Array\n  tag: Uint8Array | undefined\n  iv: Uint8Array | undefined\n}> {\n  if (!isCryptoKey(cek) && !(cek instanceof Uint8Array)) {\n    throw new TypeError(\n      invalidKeyInput(cek, 'CryptoKey', 'KeyObject', 'Uint8Array', 'JSON Web Key'),\n    )\n  }\n\n  if (iv) {\n    checkIvLength(enc, iv)\n  } else {\n    iv = generateIv(enc)\n  }\n\n  switch (enc) {\n    case 'A128CBC-HS256':\n    case 'A192CBC-HS384':\n    case 'A256CBC-HS512':\n      if (cek instanceof Uint8Array) {\n        checkCekLength(cek, parseInt(enc.slice(-3), 10))\n      }\n      return cbcEncrypt(enc, plaintext, cek, iv, aad)\n    case 'A128GCM':\n    case 'A192GCM':\n    case 'A256GCM':\n      if (cek instanceof Uint8Array) {\n        checkCekLength(cek, parseInt(enc.slice(1, 4), 10))\n      }\n      return gcmEncrypt(enc, plaintext, cek, iv, aad)\n    default:\n      throw new JOSENotSupported(unsupportedEnc)\n  }\n}\n\nexport async function decrypt(\n  enc: string,\n  cek: unknown,\n  ciphertext: Uint8Array,\n  iv: Uint8Array | undefined,\n  tag: Uint8Array | undefined,\n  aad: Uint8Array,\n): Promise<Uint8Array> {\n  if (!isCryptoKey(cek) && !(cek instanceof Uint8Array)) {\n    throw new TypeError(\n      invalidKeyInput(cek, 'CryptoKey', 'KeyObject', 'Uint8Array', 'JSON Web Key'),\n    )\n  }\n\n  if (!iv) {\n    throw new JWEInvalid('JWE Initialization Vector missing')\n  }\n  if (!tag) {\n    throw new JWEInvalid('JWE Authentication Tag missing')\n  }\n\n  checkIvLength(enc, iv)\n\n  switch (enc) {\n    case 'A128CBC-HS256':\n    case 'A192CBC-HS384':\n    case 'A256CBC-HS512':\n      if (cek instanceof Uint8Array) checkCekLength(cek, parseInt(enc.slice(-3), 10))\n      return cbcDecrypt(enc, cek, ciphertext, iv, tag, aad)\n    case 'A128GCM':\n    case 'A192GCM':\n    case 'A256GCM':\n      if (cek instanceof Uint8Array) checkCekLength(cek, parseInt(enc.slice(1, 4), 10))\n      return gcmDecrypt(enc, cek, ciphertext, iv, tag, aad)\n    default:\n      throw new JOSENotSupported(unsupportedEnc)\n  }\n}\n"
  },
  {
    "path": "src/lib/crypto_key.ts",
    "content": "import type * as types from '../types.d.ts'\n\nconst unusable = (name: string | number, prop = 'algorithm.name') =>\n  new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`)\n\nconst isAlgorithm = <T extends KeyAlgorithm>(\n  algorithm: KeyAlgorithm,\n  name: string,\n): algorithm is T => algorithm.name === name\n\nfunction getHashLength(hash: KeyAlgorithm) {\n  return parseInt(hash.name.slice(4), 10)\n}\n\nfunction checkHashLength(algorithm: { hash: KeyAlgorithm }, expected: number) {\n  const actual = getHashLength(algorithm.hash)\n  if (actual !== expected) throw unusable(`SHA-${expected}`, 'algorithm.hash')\n}\n\nfunction getNamedCurve(alg: string) {\n  switch (alg) {\n    case 'ES256':\n      return 'P-256'\n    case 'ES384':\n      return 'P-384'\n    case 'ES512':\n      return 'P-521'\n    default:\n      throw new Error('unreachable')\n  }\n}\n\nfunction checkUsage(key: types.CryptoKey, usage?: KeyUsage) {\n  if (usage && !key.usages.includes(usage)) {\n    throw new TypeError(\n      `CryptoKey does not support this operation, its usages must include ${usage}.`,\n    )\n  }\n}\n\nexport function checkSigCryptoKey(key: types.CryptoKey, alg: string, usage: KeyUsage) {\n  switch (alg) {\n    case 'HS256':\n    case 'HS384':\n    case 'HS512': {\n      if (!isAlgorithm<HmacKeyAlgorithm>(key.algorithm, 'HMAC')) throw unusable('HMAC')\n      checkHashLength(key.algorithm, parseInt(alg.slice(2), 10))\n      break\n    }\n    case 'RS256':\n    case 'RS384':\n    case 'RS512': {\n      if (!isAlgorithm<RsaHashedKeyAlgorithm>(key.algorithm, 'RSASSA-PKCS1-v1_5'))\n        throw unusable('RSASSA-PKCS1-v1_5')\n      checkHashLength(key.algorithm, parseInt(alg.slice(2), 10))\n      break\n    }\n    case 'PS256':\n    case 'PS384':\n    case 'PS512': {\n      if (!isAlgorithm<RsaHashedKeyAlgorithm>(key.algorithm, 'RSA-PSS')) throw unusable('RSA-PSS')\n      checkHashLength(key.algorithm, parseInt(alg.slice(2), 10))\n      break\n    }\n    case 'Ed25519': // Fall through\n    case 'EdDSA': {\n      if (!isAlgorithm(key.algorithm, 'Ed25519')) throw unusable('Ed25519')\n      break\n    }\n    case 'ML-DSA-44': // Fall through\n    case 'ML-DSA-65': // Fall through\n    case 'ML-DSA-87': {\n      if (!isAlgorithm(key.algorithm, alg)) throw unusable(alg)\n      break\n    }\n    case 'ES256':\n    case 'ES384':\n    case 'ES512': {\n      if (!isAlgorithm<EcKeyAlgorithm>(key.algorithm, 'ECDSA')) throw unusable('ECDSA')\n      const expected = getNamedCurve(alg)\n      const actual = key.algorithm.namedCurve\n      if (actual !== expected) throw unusable(expected, 'algorithm.namedCurve')\n      break\n    }\n    default:\n      throw new TypeError('CryptoKey does not support this operation')\n  }\n\n  checkUsage(key, usage)\n}\n\nexport function checkEncCryptoKey(key: types.CryptoKey, alg: string, usage?: KeyUsage) {\n  switch (alg) {\n    case 'A128GCM':\n    case 'A192GCM':\n    case 'A256GCM': {\n      if (!isAlgorithm<AesKeyAlgorithm>(key.algorithm, 'AES-GCM')) throw unusable('AES-GCM')\n      const expected = parseInt(alg.slice(1, 4), 10)\n      const actual = key.algorithm.length\n      if (actual !== expected) throw unusable(expected, 'algorithm.length')\n      break\n    }\n    case 'A128KW':\n    case 'A192KW':\n    case 'A256KW': {\n      if (!isAlgorithm<AesKeyAlgorithm>(key.algorithm, 'AES-KW')) throw unusable('AES-KW')\n      const expected = parseInt(alg.slice(1, 4), 10)\n      const actual = key.algorithm.length\n      if (actual !== expected) throw unusable(expected, 'algorithm.length')\n      break\n    }\n    case 'ECDH': {\n      switch (key.algorithm.name) {\n        case 'ECDH':\n        case 'X25519':\n          break\n        default:\n          throw unusable('ECDH or X25519')\n      }\n      break\n    }\n    case 'PBES2-HS256+A128KW':\n    case 'PBES2-HS384+A192KW':\n    case 'PBES2-HS512+A256KW':\n      if (!isAlgorithm(key.algorithm, 'PBKDF2')) throw unusable('PBKDF2')\n      break\n    case 'RSA-OAEP':\n    case 'RSA-OAEP-256':\n    case 'RSA-OAEP-384':\n    case 'RSA-OAEP-512': {\n      if (!isAlgorithm<RsaHashedKeyAlgorithm>(key.algorithm, 'RSA-OAEP')) throw unusable('RSA-OAEP')\n      checkHashLength(key.algorithm, parseInt(alg.slice(9), 10) || 1)\n      break\n    }\n    default:\n      throw new TypeError('CryptoKey does not support this operation')\n  }\n\n  checkUsage(key, usage)\n}\n"
  },
  {
    "path": "src/lib/deflate.ts",
    "content": "import { JOSENotSupported, JWEInvalid } from '../util/errors.js'\nimport { concat } from './buffer_utils.js'\n\nfunction supported(name: 'CompressionStream' | 'DecompressionStream') {\n  if (typeof globalThis[name] === 'undefined') {\n    throw new JOSENotSupported(\n      `JWE \"zip\" (Compression Algorithm) Header Parameter requires the ${name} API.`,\n    )\n  }\n}\n\nexport async function compress(input: Uint8Array): Promise<Uint8Array> {\n  supported('CompressionStream')\n\n  const cs = new CompressionStream('deflate-raw')\n  const writer = cs.writable.getWriter()\n  writer.write(input as Uint8Array<ArrayBuffer>).catch(() => {})\n  writer.close().catch(() => {})\n\n  const chunks: Uint8Array[] = []\n  const reader = cs.readable.getReader()\n  for (;;) {\n    const { value, done } = await reader.read()\n    if (done) break\n    chunks.push(value)\n  }\n\n  return concat(...chunks)\n}\n\nexport async function decompress(input: Uint8Array, maxLength: number): Promise<Uint8Array> {\n  supported('DecompressionStream')\n\n  const ds = new DecompressionStream('deflate-raw')\n  const writer = ds.writable.getWriter()\n  writer.write(input as Uint8Array<ArrayBuffer>).catch(() => {})\n  writer.close().catch(() => {})\n\n  const chunks: Uint8Array[] = []\n  let length = 0\n  const reader = ds.readable.getReader()\n  for (;;) {\n    const { value, done } = await reader.read()\n    if (done) break\n    chunks.push(value)\n    length += value.byteLength\n    if (maxLength !== Infinity && length > maxLength) {\n      throw new JWEInvalid('Decompressed plaintext exceeded the configured limit')\n    }\n  }\n\n  return concat(...chunks)\n}\n"
  },
  {
    "path": "src/lib/ecdhes.ts",
    "content": "import type * as types from '../types.d.ts'\nimport { encode, concat, uint32be } from './buffer_utils.js'\nimport { checkEncCryptoKey } from './crypto_key.js'\nimport { digest } from './helpers.js'\n\nfunction lengthAndInput(input: Uint8Array) {\n  return concat(uint32be(input.length), input)\n}\n\n/**\n * Concat KDF implementation\n *\n * @param Z - Shared secret from key-agreement scheme\n * @param L - Length of derived keying material in bits\n * @param OtherInfo - Context and application specific data\n */\nasync function concatKdf(Z: Uint8Array, L: number, OtherInfo: Uint8Array) {\n  // dkLen = L (in bits), converted to bytes for output length\n  const dkLen = L >> 3\n  // Hash output length in bytes (SHA-256 produces 32 bytes)\n  const hashLen = 32\n  // Number of hash function calls needed\n  const reps = Math.ceil(dkLen / hashLen)\n  // Initialize output buffer for concatenated hash results\n  const dk = new Uint8Array(reps * hashLen)\n\n  // Perform reps iterations of the hash function\n  for (let i = 1; i <= reps; i++) {\n    // Construct Hash_i input: Counter || Z || OtherInfo\n    const hashInput = new Uint8Array(4 + Z.length + OtherInfo.length)\n    hashInput.set(uint32be(i), 0) // 32-bit big-endian counter\n    hashInput.set(Z, 4) // Shared secret Z\n    hashInput.set(OtherInfo, 4 + Z.length) // OtherInfo\n\n    // Hash_i = Hash(Counter || Z || OtherInfo)\n    const hashResult = await digest('sha256', hashInput)\n    dk.set(hashResult, (i - 1) * hashLen)\n  }\n\n  // Return leading L bits of dk (truncate to exact length needed)\n  return dk.slice(0, dkLen)\n}\n\n/**\n * ECDH-ES Key Agreement with Concat KDF\n *\n * @param publicKey\n * @param privateKey\n * @param algorithm - AlgorithmID: For Direct Key Agreement (ECDH-ES), this is the \"enc\" value. For\n *   Key Agreement with Key Wrapping, this is the \"alg\" value\n * @param keyLength - Keydatalen: Number of bits in the desired output key\n * @param apu - PartyUInfo: Agreement PartyUInfo value (information about the producer)\n * @param apv - PartyVInfo: Agreement PartyVInfo value (information about the recipient)\n */\nexport async function deriveKey(\n  publicKey: types.CryptoKey,\n  privateKey: types.CryptoKey,\n  algorithm: string,\n  keyLength: number,\n  apu: Uint8Array = new Uint8Array(),\n  apv: Uint8Array = new Uint8Array(),\n) {\n  checkEncCryptoKey(publicKey, 'ECDH')\n  checkEncCryptoKey(privateKey, 'ECDH', 'deriveBits')\n\n  // Construct OtherInfo\n  const algorithmID = lengthAndInput(encode(algorithm))\n  const partyUInfo = lengthAndInput(apu)\n  const partyVInfo = lengthAndInput(apv)\n  const suppPubInfo = uint32be(keyLength)\n  const suppPrivInfo = new Uint8Array()\n\n  const otherInfo = concat(algorithmID, partyUInfo, partyVInfo, suppPubInfo, suppPrivInfo)\n\n  // Perform ECDH to get the shared secret Z\n  const Z = new Uint8Array(\n    await crypto.subtle.deriveBits(\n      {\n        name: publicKey.algorithm.name,\n        public: publicKey,\n      },\n      privateKey,\n      getEcdhBitLength(publicKey),\n    ),\n  )\n\n  // Apply Concat KDF to derive the final key material\n  return concatKdf(Z, keyLength, otherInfo)\n}\n\nfunction getEcdhBitLength(publicKey: CryptoKey) {\n  if (publicKey.algorithm.name === 'X25519') {\n    return 256\n  }\n\n  return (\n    Math.ceil(parseInt((publicKey.algorithm as EcKeyAlgorithm).namedCurve.slice(-3), 10) / 8) << 3\n  )\n}\n\nexport function allowed(key: types.CryptoKey) {\n  switch ((key.algorithm as EcKeyAlgorithm).namedCurve) {\n    case 'P-256':\n    case 'P-384':\n    case 'P-521':\n      return true\n    default:\n      return key.algorithm.name === 'X25519'\n  }\n}\n"
  },
  {
    "path": "src/lib/helpers.ts",
    "content": "import { decode } from '../util/base64url.js'\n\nexport const unprotected = Symbol()\n\nexport function assertNotSet(value: unknown, name: string): void {\n  if (value) {\n    throw new TypeError(`${name} can only be called once`)\n  }\n}\n\nexport function decodeBase64url(\n  value: string,\n  label: string,\n  ErrorClass: new (message: string) => Error,\n): Uint8Array {\n  try {\n    return decode(value)\n  } catch {\n    throw new ErrorClass(`Failed to base64url decode the ${label}`)\n  }\n}\n\nexport async function digest(\n  algorithm: 'sha256' | 'sha384' | 'sha512',\n  data: Uint8Array,\n): Promise<Uint8Array> {\n  const subtleDigest = `SHA-${algorithm.slice(-3)}`\n  return new Uint8Array(await crypto.subtle.digest(subtleDigest, data as Uint8Array<ArrayBuffer>))\n}\n"
  },
  {
    "path": "src/lib/invalid_key_input.ts",
    "content": "function message(msg: string, actual: unknown, ...types: Array<string | null>) {\n  types = types.filter(Boolean)\n  if (types.length > 2) {\n    const last = types.pop()\n    msg += `one of type ${types.join(', ')}, or ${last}.`\n  } else if (types.length === 2) {\n    msg += `one of type ${types[0]} or ${types[1]}.`\n  } else {\n    msg += `of type ${types[0]}.`\n  }\n\n  if (actual == null) {\n    msg += ` Received ${actual}`\n  } else if (typeof actual === 'function' && actual.name) {\n    msg += ` Received function ${actual.name}`\n  } else if (typeof actual === 'object' && actual != null) {\n    if (actual.constructor?.name) {\n      msg += ` Received an instance of ${actual.constructor.name}`\n    }\n  }\n\n  return msg\n}\n\nexport const invalidKeyInput = (actual: unknown, ...types: string[]) =>\n  message('Key must be ', actual, ...types)\n\nexport const withAlg = (alg: string, actual: unknown, ...types: Array<string | null>) =>\n  message(`Key for the ${alg} algorithm must be `, actual, ...types)\n"
  },
  {
    "path": "src/lib/is_key_like.ts",
    "content": "import type * as types from '../types.d.ts'\n\nexport function assertCryptoKey(key: unknown): asserts key is types.CryptoKey {\n  if (!isCryptoKey(key)) {\n    throw new Error('CryptoKey instance expected')\n  }\n}\n\nexport const isCryptoKey = (key: unknown): key is types.CryptoKey => {\n  // @ts-ignore\n  if (key?.[Symbol.toStringTag] === 'CryptoKey') return true\n  try {\n    return key instanceof CryptoKey\n  } catch {\n    return false\n  }\n}\n\nexport const isKeyObject = <T extends types.KeyObject = types.KeyObject>(key: unknown): key is T =>\n  // @ts-ignore\n  key?.[Symbol.toStringTag] === 'KeyObject'\n\nexport const isKeyLike = (key: unknown): key is types.CryptoKey | types.KeyObject =>\n  isCryptoKey(key) || isKeyObject(key)\n"
  },
  {
    "path": "src/lib/jwk_to_key.ts",
    "content": "import { JOSENotSupported } from '../util/errors.js'\nimport type * as types from '../types.d.ts'\n\nconst unsupportedAlg = 'Invalid or unsupported JWK \"alg\" (Algorithm) Parameter value'\n\nfunction subtleMapping(jwk: types.JWK): {\n  algorithm: RsaHashedImportParams | EcKeyAlgorithm | Algorithm\n  keyUsages: KeyUsage[]\n} {\n  let algorithm: RsaHashedImportParams | EcKeyAlgorithm | Algorithm\n  let keyUsages: KeyUsage[]\n\n  switch (jwk.kty) {\n    case 'AKP': {\n      switch (jwk.alg) {\n        case 'ML-DSA-44':\n        case 'ML-DSA-65':\n        case 'ML-DSA-87':\n          algorithm = { name: jwk.alg }\n          keyUsages = jwk.priv ? ['sign'] : ['verify']\n          break\n        default:\n          throw new JOSENotSupported(unsupportedAlg)\n      }\n      break\n    }\n    case 'RSA': {\n      switch (jwk.alg) {\n        case 'PS256':\n        case 'PS384':\n        case 'PS512':\n          algorithm = { name: 'RSA-PSS', hash: `SHA-${jwk.alg.slice(-3)}` }\n          keyUsages = jwk.d ? ['sign'] : ['verify']\n          break\n        case 'RS256':\n        case 'RS384':\n        case 'RS512':\n          algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${jwk.alg.slice(-3)}` }\n          keyUsages = jwk.d ? ['sign'] : ['verify']\n          break\n        case 'RSA-OAEP':\n        case 'RSA-OAEP-256':\n        case 'RSA-OAEP-384':\n        case 'RSA-OAEP-512':\n          algorithm = {\n            name: 'RSA-OAEP',\n            hash: `SHA-${parseInt(jwk.alg.slice(-3), 10) || 1}`,\n          }\n          keyUsages = jwk.d ? ['decrypt', 'unwrapKey'] : ['encrypt', 'wrapKey']\n          break\n        default:\n          throw new JOSENotSupported(unsupportedAlg)\n      }\n      break\n    }\n    case 'EC': {\n      switch (jwk.alg) {\n        case 'ES256':\n        case 'ES384':\n        case 'ES512':\n          algorithm = {\n            name: 'ECDSA',\n            namedCurve: { ES256: 'P-256', ES384: 'P-384', ES512: 'P-521' }[jwk.alg],\n          }\n          keyUsages = jwk.d ? ['sign'] : ['verify']\n          break\n        case 'ECDH-ES':\n        case 'ECDH-ES+A128KW':\n        case 'ECDH-ES+A192KW':\n        case 'ECDH-ES+A256KW':\n          algorithm = { name: 'ECDH', namedCurve: jwk.crv! }\n          keyUsages = jwk.d ? ['deriveBits'] : []\n          break\n        default:\n          throw new JOSENotSupported(unsupportedAlg)\n      }\n      break\n    }\n    case 'OKP': {\n      switch (jwk.alg) {\n        case 'Ed25519': // Fall through\n        case 'EdDSA':\n          algorithm = { name: 'Ed25519' }\n          keyUsages = jwk.d ? ['sign'] : ['verify']\n          break\n        case 'ECDH-ES':\n        case 'ECDH-ES+A128KW':\n        case 'ECDH-ES+A192KW':\n        case 'ECDH-ES+A256KW':\n          algorithm = { name: jwk.crv! }\n          keyUsages = jwk.d ? ['deriveBits'] : []\n          break\n        default:\n          throw new JOSENotSupported(unsupportedAlg)\n      }\n      break\n    }\n    default:\n      throw new JOSENotSupported('Invalid or unsupported JWK \"kty\" (Key Type) Parameter value')\n  }\n\n  return { algorithm, keyUsages }\n}\n\nexport async function jwkToKey(jwk: types.JWK): Promise<types.CryptoKey> {\n  if (!jwk.alg) {\n    throw new TypeError('\"alg\" argument is required when \"jwk.alg\" is not present')\n  }\n\n  const { algorithm, keyUsages } = subtleMapping(jwk)\n\n  const keyData: types.JWK = { ...jwk }\n  if (keyData.kty !== 'AKP') {\n    delete keyData.alg\n  }\n  delete keyData.use\n\n  return crypto.subtle.importKey(\n    'jwk',\n    keyData,\n    algorithm,\n    jwk.ext ?? (jwk.d || jwk.priv ? false : true),\n    (jwk.key_ops as KeyUsage[]) ?? keyUsages,\n  )\n}\n"
  },
  {
    "path": "src/lib/jwt_claims_set.ts",
    "content": "import type * as types from '../types.d.ts'\nimport { JWTClaimValidationFailed, JWTExpired, JWTInvalid } from '../util/errors.js'\nimport { encoder, decoder } from './buffer_utils.js'\nimport { isObject } from './type_checks.js'\n\nconst epoch = (date: Date) => Math.floor(date.getTime() / 1000)\n\nconst minute = 60\nconst hour = minute * 60\nconst day = hour * 24\nconst week = day * 7\nconst year = day * 365.25\n\nconst REGEX =\n  /^(\\+|\\-)? ?(\\d+|\\d+\\.\\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i\n\nexport function secs(str: string): number {\n  const matched = REGEX.exec(str)\n\n  if (!matched || (matched[4] && matched[1])) {\n    throw new TypeError('Invalid time period format')\n  }\n\n  const value = parseFloat(matched[2])\n  const unit = matched[3].toLowerCase()\n\n  let numericDate: number\n\n  switch (unit) {\n    case 'sec':\n    case 'secs':\n    case 'second':\n    case 'seconds':\n    case 's':\n      numericDate = Math.round(value)\n      break\n    case 'minute':\n    case 'minutes':\n    case 'min':\n    case 'mins':\n    case 'm':\n      numericDate = Math.round(value * minute)\n      break\n    case 'hour':\n    case 'hours':\n    case 'hr':\n    case 'hrs':\n    case 'h':\n      numericDate = Math.round(value * hour)\n      break\n    case 'day':\n    case 'days':\n    case 'd':\n      numericDate = Math.round(value * day)\n      break\n    case 'week':\n    case 'weeks':\n    case 'w':\n      numericDate = Math.round(value * week)\n      break\n    // years matched\n    default:\n      numericDate = Math.round(value * year)\n      break\n  }\n\n  if (matched[1] === '-' || matched[4] === 'ago') {\n    return -numericDate\n  }\n\n  return numericDate\n}\n\nfunction validateInput(label: string, input: number) {\n  if (!Number.isFinite(input)) {\n    throw new TypeError(`Invalid ${label} input`)\n  }\n\n  return input\n}\n\nconst normalizeTyp = (value: string) => {\n  if (value.includes('/')) {\n    return value.toLowerCase()\n  }\n\n  return `application/${value.toLowerCase()}`\n}\n\nconst checkAudiencePresence = (audPayload: unknown, audOption: unknown[]) => {\n  if (typeof audPayload === 'string') {\n    return audOption.includes(audPayload)\n  }\n\n  if (Array.isArray(audPayload)) {\n    // Each principal intended to process the JWT MUST\n    // identify itself with a value in the audience claim\n    return audOption.some(Set.prototype.has.bind(new Set(audPayload)))\n  }\n\n  return false\n}\n\nexport function validateClaimsSet(\n  protectedHeader: types.JWEHeaderParameters | types.JWSHeaderParameters,\n  encodedPayload: Uint8Array,\n  options: types.JWTClaimVerificationOptions = {},\n) {\n  let payload!: { [propName: string]: unknown }\n  try {\n    payload = JSON.parse(decoder.decode(encodedPayload))\n  } catch {\n    //\n  }\n\n  if (!isObject(payload)) {\n    throw new JWTInvalid('JWT Claims Set must be a top-level JSON object')\n  }\n\n  const { typ } = options\n  if (\n    typ &&\n    (typeof protectedHeader!.typ !== 'string' ||\n      normalizeTyp(protectedHeader!.typ) !== normalizeTyp(typ))\n  ) {\n    throw new JWTClaimValidationFailed(\n      'unexpected \"typ\" JWT header value',\n      payload,\n      'typ',\n      'check_failed',\n    )\n  }\n\n  const { requiredClaims = [], issuer, subject, audience, maxTokenAge } = options\n\n  const presenceCheck = [...requiredClaims]\n\n  if (maxTokenAge !== undefined) presenceCheck.push('iat')\n  if (audience !== undefined) presenceCheck.push('aud')\n  if (subject !== undefined) presenceCheck.push('sub')\n  if (issuer !== undefined) presenceCheck.push('iss')\n\n  for (const claim of new Set(presenceCheck.reverse())) {\n    if (!(claim in payload)) {\n      throw new JWTClaimValidationFailed(\n        `missing required \"${claim}\" claim`,\n        payload,\n        claim,\n        'missing',\n      )\n    }\n  }\n\n  if (\n    issuer &&\n    !((Array.isArray(issuer) ? issuer : [issuer]) as unknown[]).includes(payload.iss!)\n  ) {\n    throw new JWTClaimValidationFailed(\n      'unexpected \"iss\" claim value',\n      payload,\n      'iss',\n      'check_failed',\n    )\n  }\n\n  if (subject && payload.sub !== subject) {\n    throw new JWTClaimValidationFailed(\n      'unexpected \"sub\" claim value',\n      payload,\n      'sub',\n      'check_failed',\n    )\n  }\n\n  if (\n    audience &&\n    !checkAudiencePresence(payload.aud, typeof audience === 'string' ? [audience] : audience)\n  ) {\n    throw new JWTClaimValidationFailed(\n      'unexpected \"aud\" claim value',\n      payload,\n      'aud',\n      'check_failed',\n    )\n  }\n\n  let tolerance: number\n  switch (typeof options.clockTolerance) {\n    case 'string':\n      tolerance = secs(options.clockTolerance)\n      break\n    case 'number':\n      tolerance = options.clockTolerance\n      break\n    case 'undefined':\n      tolerance = 0\n      break\n    default:\n      throw new TypeError('Invalid clockTolerance option type')\n  }\n\n  const { currentDate } = options\n  const now = epoch(currentDate || new Date())\n\n  if ((payload.iat !== undefined || maxTokenAge) && typeof payload.iat !== 'number') {\n    throw new JWTClaimValidationFailed('\"iat\" claim must be a number', payload, 'iat', 'invalid')\n  }\n\n  if (payload.nbf !== undefined) {\n    if (typeof payload.nbf !== 'number') {\n      throw new JWTClaimValidationFailed('\"nbf\" claim must be a number', payload, 'nbf', 'invalid')\n    }\n    if (payload.nbf > now + tolerance) {\n      throw new JWTClaimValidationFailed(\n        '\"nbf\" claim timestamp check failed',\n        payload,\n        'nbf',\n        'check_failed',\n      )\n    }\n  }\n\n  if (payload.exp !== undefined) {\n    if (typeof payload.exp !== 'number') {\n      throw new JWTClaimValidationFailed('\"exp\" claim must be a number', payload, 'exp', 'invalid')\n    }\n    if (payload.exp <= now - tolerance) {\n      throw new JWTExpired('\"exp\" claim timestamp check failed', payload, 'exp', 'check_failed')\n    }\n  }\n\n  if (maxTokenAge) {\n    const age = now - (payload.iat as number)\n    const max = typeof maxTokenAge === 'number' ? maxTokenAge : secs(maxTokenAge)\n\n    if (age - tolerance > max) {\n      throw new JWTExpired(\n        '\"iat\" claim timestamp check failed (too far in the past)',\n        payload,\n        'iat',\n        'check_failed',\n      )\n    }\n\n    if (age < 0 - tolerance) {\n      throw new JWTClaimValidationFailed(\n        '\"iat\" claim timestamp check failed (it should be in the past)',\n        payload,\n        'iat',\n        'check_failed',\n      )\n    }\n  }\n\n  return payload as types.JWTPayload\n}\n\nexport class JWTClaimsBuilder {\n  #payload!: types.JWTPayload\n\n  constructor(payload: types.JWTPayload) {\n    if (!isObject(payload)) {\n      throw new TypeError('JWT Claims Set MUST be an object')\n    }\n    this.#payload = structuredClone(payload)\n  }\n\n  data(): Uint8Array {\n    return encoder.encode(JSON.stringify(this.#payload))\n  }\n\n  get iss(): string | undefined {\n    return this.#payload.iss\n  }\n\n  set iss(value: string) {\n    this.#payload.iss = value\n  }\n\n  get sub(): string | undefined {\n    return this.#payload.sub\n  }\n\n  set sub(value: string) {\n    this.#payload.sub = value\n  }\n\n  get aud(): string | string[] | undefined {\n    return this.#payload.aud\n  }\n\n  set aud(value: string | string[]) {\n    this.#payload.aud = value\n  }\n\n  set jti(value: string) {\n    this.#payload.jti = value\n  }\n\n  set nbf(value: number | string | Date) {\n    if (typeof value === 'number') {\n      this.#payload.nbf = validateInput('setNotBefore', value)\n    } else if (value instanceof Date) {\n      this.#payload.nbf = validateInput('setNotBefore', epoch(value))\n    } else {\n      this.#payload.nbf = epoch(new Date()) + secs(value)\n    }\n  }\n\n  set exp(value: number | string | Date) {\n    if (typeof value === 'number') {\n      this.#payload.exp = validateInput('setExpirationTime', value)\n    } else if (value instanceof Date) {\n      this.#payload.exp = validateInput('setExpirationTime', epoch(value))\n    } else {\n      this.#payload.exp = epoch(new Date()) + secs(value)\n    }\n  }\n\n  set iat(value: number | string | Date | undefined) {\n    if (value === undefined) {\n      this.#payload.iat = epoch(new Date())\n    } else if (value instanceof Date) {\n      this.#payload.iat = validateInput('setIssuedAt', epoch(value))\n    } else if (typeof value === 'string') {\n      this.#payload.iat = validateInput('setIssuedAt', epoch(new Date()) + secs(value))\n    } else {\n      this.#payload.iat = validateInput('setIssuedAt', value)\n    }\n  }\n}\n"
  },
  {
    "path": "src/lib/key_management.ts",
    "content": "import type * as types from '../types.d.ts'\nimport type { JWEKeyManagementHeaderParameters, JWEHeaderParameters, JWK } from '../types.d.ts'\nimport * as aeskw from './aeskw.js'\nimport * as ecdhes from './ecdhes.js'\nimport * as pbes2kw from './pbes2kw.js'\nimport * as rsaes from './rsaes.js'\nimport { encode as b64u } from '../util/base64url.js'\nimport { normalizeKey } from './normalize_key.js'\nimport { JOSENotSupported, JWEInvalid } from '../util/errors.js'\nimport { decodeBase64url } from './helpers.js'\nimport { generateCek, cekLength } from './content_encryption.js'\nimport { importJWK } from '../key/import.js'\nimport { exportJWK } from '../key/export.js'\nimport { isObject } from './type_checks.js'\nimport { wrap as aesGcmKwWrap, unwrap as aesGcmKwUnwrap } from './aesgcmkw.js'\nimport { assertCryptoKey } from './is_key_like.js'\n\nconst unsupportedAlgHeader = 'Invalid or unsupported \"alg\" (JWE Algorithm) header value'\n\nfunction assertEncryptedKey(\n  encryptedKey: Uint8Array | undefined,\n): asserts encryptedKey is Uint8Array {\n  if (encryptedKey === undefined) throw new JWEInvalid('JWE Encrypted Key missing')\n}\n\nexport async function decryptKeyManagement(\n  alg: string,\n  key: types.CryptoKey | Uint8Array,\n  encryptedKey: Uint8Array | undefined,\n  joseHeader: types.JWEHeaderParameters,\n  options?: types.DecryptOptions,\n): Promise<types.CryptoKey | Uint8Array> {\n  switch (alg) {\n    case 'dir': {\n      // Direct Encryption\n      if (encryptedKey !== undefined)\n        throw new JWEInvalid('Encountered unexpected JWE Encrypted Key')\n\n      return key\n    }\n    case 'ECDH-ES':\n      // Direct Key Agreement\n      if (encryptedKey !== undefined)\n        throw new JWEInvalid('Encountered unexpected JWE Encrypted Key')\n\n    case 'ECDH-ES+A128KW':\n    case 'ECDH-ES+A192KW':\n    case 'ECDH-ES+A256KW': {\n      // Direct Key Agreement\n      if (!isObject<types.JWK>(joseHeader.epk))\n        throw new JWEInvalid(`JOSE Header \"epk\" (Ephemeral Public Key) missing or invalid`)\n\n      assertCryptoKey(key)\n      if (!ecdhes.allowed(key))\n        throw new JOSENotSupported(\n          'ECDH with the provided key is not allowed or not supported by your javascript runtime',\n        )\n\n      const epk = await importJWK(joseHeader.epk, alg)\n      assertCryptoKey(epk)\n      let partyUInfo!: Uint8Array\n      let partyVInfo!: Uint8Array\n\n      if (joseHeader.apu !== undefined) {\n        if (typeof joseHeader.apu !== 'string')\n          throw new JWEInvalid(`JOSE Header \"apu\" (Agreement PartyUInfo) invalid`)\n        partyUInfo = decodeBase64url(joseHeader.apu, 'apu', JWEInvalid)\n      }\n\n      if (joseHeader.apv !== undefined) {\n        if (typeof joseHeader.apv !== 'string')\n          throw new JWEInvalid(`JOSE Header \"apv\" (Agreement PartyVInfo) invalid`)\n        partyVInfo = decodeBase64url(joseHeader.apv, 'apv', JWEInvalid)\n      }\n\n      const sharedSecret = await ecdhes.deriveKey(\n        epk,\n        key,\n        alg === 'ECDH-ES' ? joseHeader.enc! : alg,\n        alg === 'ECDH-ES' ? cekLength(joseHeader.enc!) : parseInt(alg.slice(-5, -2), 10),\n        partyUInfo,\n        partyVInfo,\n      )\n\n      if (alg === 'ECDH-ES') return sharedSecret\n\n      // Key Agreement with Key Wrapping\n      assertEncryptedKey(encryptedKey)\n\n      return aeskw.unwrap(alg.slice(-6), sharedSecret, encryptedKey)\n    }\n    case 'RSA-OAEP':\n    case 'RSA-OAEP-256':\n    case 'RSA-OAEP-384':\n    case 'RSA-OAEP-512': {\n      // Key Encryption (RSA)\n      assertEncryptedKey(encryptedKey)\n      assertCryptoKey(key)\n      return rsaes.decrypt(alg, key, encryptedKey)\n    }\n    case 'PBES2-HS256+A128KW':\n    case 'PBES2-HS384+A192KW':\n    case 'PBES2-HS512+A256KW': {\n      // Key Encryption (PBES2)\n      assertEncryptedKey(encryptedKey)\n\n      if (typeof joseHeader.p2c !== 'number')\n        throw new JWEInvalid(`JOSE Header \"p2c\" (PBES2 Count) missing or invalid`)\n\n      const p2cLimit = options?.maxPBES2Count || 10_000\n\n      if (joseHeader.p2c > p2cLimit)\n        throw new JWEInvalid(`JOSE Header \"p2c\" (PBES2 Count) out is of acceptable bounds`)\n\n      if (typeof joseHeader.p2s !== 'string')\n        throw new JWEInvalid(`JOSE Header \"p2s\" (PBES2 Salt) missing or invalid`)\n\n      let p2s: Uint8Array\n      p2s = decodeBase64url(joseHeader.p2s, 'p2s', JWEInvalid)\n      return pbes2kw.unwrap(alg, key, encryptedKey, joseHeader.p2c, p2s)\n    }\n    case 'A128KW':\n    case 'A192KW':\n    case 'A256KW': {\n      // Key Wrapping (AES KW)\n      assertEncryptedKey(encryptedKey)\n\n      return aeskw.unwrap(alg, key, encryptedKey)\n    }\n    case 'A128GCMKW':\n    case 'A192GCMKW':\n    case 'A256GCMKW': {\n      // Key Wrapping (AES GCM KW)\n      assertEncryptedKey(encryptedKey)\n\n      if (typeof joseHeader.iv !== 'string')\n        throw new JWEInvalid(`JOSE Header \"iv\" (Initialization Vector) missing or invalid`)\n\n      if (typeof joseHeader.tag !== 'string')\n        throw new JWEInvalid(`JOSE Header \"tag\" (Authentication Tag) missing or invalid`)\n\n      let iv: Uint8Array\n      iv = decodeBase64url(joseHeader.iv, 'iv', JWEInvalid)\n      let tag: Uint8Array\n      tag = decodeBase64url(joseHeader.tag, 'tag', JWEInvalid)\n\n      return aesGcmKwUnwrap(alg, key, encryptedKey, iv, tag)\n    }\n    default: {\n      throw new JOSENotSupported(unsupportedAlgHeader)\n    }\n  }\n}\n\nexport async function encryptKeyManagement(\n  alg: string,\n  enc: string,\n  key: types.CryptoKey | Uint8Array,\n  providedCek?: Uint8Array,\n  providedParameters: JWEKeyManagementHeaderParameters = {},\n): Promise<{\n  cek: types.CryptoKey | Uint8Array\n  encryptedKey?: Uint8Array\n  parameters?: JWEHeaderParameters\n}> {\n  let encryptedKey: Uint8Array | undefined\n  let parameters: (JWEHeaderParameters & { epk?: JWK }) | undefined\n  let cek: types.CryptoKey | Uint8Array\n\n  switch (alg) {\n    case 'dir': {\n      // Direct Encryption\n      cek = key\n      break\n    }\n    case 'ECDH-ES':\n    case 'ECDH-ES+A128KW':\n    case 'ECDH-ES+A192KW':\n    case 'ECDH-ES+A256KW': {\n      assertCryptoKey(key)\n      // Direct Key Agreement\n      if (!ecdhes.allowed(key)) {\n        throw new JOSENotSupported(\n          'ECDH with the provided key is not allowed or not supported by your javascript runtime',\n        )\n      }\n      const { apu, apv } = providedParameters\n      let ephemeralKey: types.CryptoKey\n      if (providedParameters.epk) {\n        ephemeralKey = (await normalizeKey(providedParameters.epk, alg)) as types.CryptoKey\n      } else {\n        ephemeralKey = (\n          await crypto.subtle.generateKey(key.algorithm as EcKeyAlgorithm, true, ['deriveBits'])\n        ).privateKey\n      }\n      const { x, y, crv, kty } = await exportJWK(ephemeralKey!)\n      const sharedSecret = await ecdhes.deriveKey(\n        key,\n        ephemeralKey,\n        alg === 'ECDH-ES' ? enc : alg,\n        alg === 'ECDH-ES' ? cekLength(enc) : parseInt(alg.slice(-5, -2), 10),\n        apu,\n        apv,\n      )\n      parameters = { epk: { x, crv, kty } }\n      if (kty === 'EC') parameters.epk!.y = y\n      if (apu) parameters.apu = b64u(apu)\n      if (apv) parameters.apv = b64u(apv)\n\n      if (alg === 'ECDH-ES') {\n        cek = sharedSecret\n        break\n      }\n\n      // Key Agreement with Key Wrapping\n      cek = providedCek || generateCek(enc)\n      const kwAlg = alg.slice(-6)\n      encryptedKey = await aeskw.wrap(kwAlg, sharedSecret, cek)\n      break\n    }\n    case 'RSA-OAEP':\n    case 'RSA-OAEP-256':\n    case 'RSA-OAEP-384':\n    case 'RSA-OAEP-512': {\n      // Key Encryption (RSA)\n      cek = providedCek || generateCek(enc)\n      assertCryptoKey(key)\n      encryptedKey = await rsaes.encrypt(alg, key, cek)\n      break\n    }\n    case 'PBES2-HS256+A128KW':\n    case 'PBES2-HS384+A192KW':\n    case 'PBES2-HS512+A256KW': {\n      // Key Encryption (PBES2)\n      cek = providedCek || generateCek(enc)\n      const { p2c, p2s } = providedParameters\n      ;({ encryptedKey, ...parameters } = await pbes2kw.wrap(alg, key, cek, p2c, p2s))\n      break\n    }\n    case 'A128KW':\n    case 'A192KW':\n    case 'A256KW': {\n      // Key Wrapping (AES KW)\n      cek = providedCek || generateCek(enc)\n      encryptedKey = await aeskw.wrap(alg, key, cek)\n      break\n    }\n    case 'A128GCMKW':\n    case 'A192GCMKW':\n    case 'A256GCMKW': {\n      // Key Wrapping (AES GCM KW)\n      cek = providedCek || generateCek(enc)\n      const { iv } = providedParameters\n      ;({ encryptedKey, ...parameters } = await aesGcmKwWrap(alg, key, cek, iv))\n      break\n    }\n    default: {\n      throw new JOSENotSupported(unsupportedAlgHeader)\n    }\n  }\n\n  return { cek, encryptedKey, parameters }\n}\n"
  },
  {
    "path": "src/lib/key_to_jwk.ts",
    "content": "import type * as types from '../types.d.ts'\nimport { invalidKeyInput } from './invalid_key_input.js'\nimport { encode as b64u } from '../util/base64url.js'\nimport { isCryptoKey, isKeyObject } from './is_key_like.js'\n\ninterface ExportOptions {\n  format: 'jwk'\n}\n\ninterface ExtractableKeyObject extends types.KeyObject {\n  export(arg: ExportOptions): types.JWK\n  export(): Uint8Array\n}\n\nexport async function keyToJWK(key: unknown): Promise<types.JWK> {\n  if (isKeyObject(key)) {\n    if (key.type === 'secret') {\n      key = (key as ExtractableKeyObject).export()\n    } else {\n      return (key as ExtractableKeyObject).export({ format: 'jwk' })\n    }\n  }\n  if (key instanceof Uint8Array) {\n    return {\n      kty: 'oct',\n      k: b64u(key),\n    }\n  }\n  if (!isCryptoKey(key)) {\n    throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'KeyObject', 'Uint8Array'))\n  }\n  if (!key.extractable) {\n    throw new TypeError('non-extractable CryptoKey cannot be exported as a JWK')\n  }\n  const { ext, key_ops, alg, use, ...jwk } = await crypto.subtle.exportKey('jwk', key)\n\n  if (jwk.kty === 'AKP') {\n    ;(jwk as types.JWK).alg = alg\n  }\n\n  return jwk as types.JWK\n}\n"
  },
  {
    "path": "src/lib/normalize_key.ts",
    "content": "import type * as types from '../types.d.ts'\nimport { isJWK } from './type_checks.js'\nimport { decode } from '../util/base64url.js'\nimport { jwkToKey } from './jwk_to_key.js'\nimport { isCryptoKey, isKeyObject } from './is_key_like.js'\n\nconst unusableForAlg = 'given KeyObject instance cannot be used for this algorithm'\n\nlet cache: WeakMap<object, Record<string, CryptoKey>>\n\ninterface ConvertableKeyObject extends types.KeyObject {\n  export(): Uint8Array\n  export(opts: { format: 'jwk' }): types.JWK\n  asymmetricKeyType?: string\n  asymmetricKeyDetails?: { namedCurve?: string }\n  toCryptoKey(\n    alg:\n      | AlgorithmIdentifier\n      | RsaHashedImportParams\n      | EcKeyImportParams\n      | HmacImportParams\n      | AesKeyAlgorithm,\n    extractable: boolean,\n    usages: string[],\n  ): types.CryptoKey\n}\n\nconst handleJWK = async (\n  key: types.KeyObject | types.JWK,\n  jwk: types.JWK,\n  alg: string,\n  freeze = false,\n) => {\n  cache ||= new WeakMap()\n  let cached = cache.get(key)\n  if (cached?.[alg]) {\n    return cached[alg]\n  }\n\n  const cryptoKey = await jwkToKey({ ...jwk, alg })\n  if (freeze) Object.freeze(key)\n  if (!cached) {\n    cache.set(key, { [alg]: cryptoKey })\n  } else {\n    cached[alg] = cryptoKey\n  }\n  return cryptoKey\n}\n\nconst handleKeyObject = (keyObject: ConvertableKeyObject, alg: string) => {\n  cache ||= new WeakMap()\n  let cached = cache.get(keyObject)\n  if (cached?.[alg]) {\n    return cached[alg]\n  }\n\n  const isPublic = keyObject.type === 'public'\n  const extractable = isPublic ? true : false\n\n  let cryptoKey: types.CryptoKey | undefined\n  if (keyObject.asymmetricKeyType === 'x25519') {\n    switch (alg) {\n      case 'ECDH-ES':\n      case 'ECDH-ES+A128KW':\n      case 'ECDH-ES+A192KW':\n      case 'ECDH-ES+A256KW':\n        break\n\n      default:\n        throw new TypeError(unusableForAlg)\n    }\n\n    cryptoKey = keyObject.toCryptoKey(\n      keyObject.asymmetricKeyType,\n      extractable,\n      isPublic ? [] : ['deriveBits'],\n    )\n  }\n\n  if (keyObject.asymmetricKeyType === 'ed25519') {\n    if (alg !== 'EdDSA' && alg !== 'Ed25519') {\n      throw new TypeError(unusableForAlg)\n    }\n\n    cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [\n      isPublic ? 'verify' : 'sign',\n    ])\n  }\n\n  switch (keyObject.asymmetricKeyType) {\n    case 'ml-dsa-44':\n    case 'ml-dsa-65':\n    case 'ml-dsa-87': {\n      if (alg !== keyObject.asymmetricKeyType.toUpperCase()) {\n        throw new TypeError(unusableForAlg)\n      }\n\n      cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [\n        isPublic ? 'verify' : 'sign',\n      ])\n    }\n  }\n\n  if (keyObject.asymmetricKeyType === 'rsa') {\n    let hash: string\n    switch (alg) {\n      case 'RSA-OAEP':\n        hash = 'SHA-1'\n        break\n      case 'RS256':\n      case 'PS256':\n      case 'RSA-OAEP-256':\n        hash = 'SHA-256'\n        break\n      case 'RS384':\n      case 'PS384':\n      case 'RSA-OAEP-384':\n        hash = 'SHA-384'\n        break\n      case 'RS512':\n      case 'PS512':\n      case 'RSA-OAEP-512':\n        hash = 'SHA-512'\n        break\n\n      default:\n        throw new TypeError(unusableForAlg)\n    }\n\n    if (alg.startsWith('RSA-OAEP')) {\n      return keyObject.toCryptoKey(\n        {\n          name: 'RSA-OAEP',\n          hash,\n        },\n        extractable,\n        isPublic ? ['encrypt'] : ['decrypt'],\n      )\n    }\n\n    cryptoKey = keyObject.toCryptoKey(\n      {\n        name: alg.startsWith('PS') ? 'RSA-PSS' : 'RSASSA-PKCS1-v1_5',\n        hash,\n      },\n      extractable,\n      [isPublic ? 'verify' : 'sign'],\n    )\n  }\n\n  if (keyObject.asymmetricKeyType === 'ec') {\n    const nist = new Map<unknown, string>([\n      ['prime256v1', 'P-256'],\n      ['secp384r1', 'P-384'],\n      ['secp521r1', 'P-521'],\n    ])\n\n    const namedCurve = nist.get(keyObject.asymmetricKeyDetails?.namedCurve)\n    if (!namedCurve) {\n      throw new TypeError(unusableForAlg)\n    }\n\n    const expectedCurve: Record<string, string> = { ES256: 'P-256', ES384: 'P-384', ES512: 'P-521' }\n    if (expectedCurve[alg] && namedCurve === expectedCurve[alg]) {\n      cryptoKey = keyObject.toCryptoKey(\n        {\n          name: 'ECDSA',\n          namedCurve,\n        },\n        extractable,\n        [isPublic ? 'verify' : 'sign'],\n      )\n    }\n\n    if (alg.startsWith('ECDH-ES')) {\n      cryptoKey = keyObject.toCryptoKey(\n        {\n          name: 'ECDH',\n          namedCurve,\n        },\n        extractable,\n        isPublic ? [] : ['deriveBits'],\n      )\n    }\n  }\n\n  if (!cryptoKey) {\n    throw new TypeError(unusableForAlg)\n  }\n\n  if (!cached) {\n    cache.set(keyObject, { [alg]: cryptoKey })\n  } else {\n    cached[alg] = cryptoKey\n  }\n  return cryptoKey\n}\n\nexport async function normalizeKey(\n  key: types.CryptoKey | types.KeyObject | types.JWK | Uint8Array,\n  alg: string,\n): Promise<types.CryptoKey | Uint8Array> {\n  if (key instanceof Uint8Array) {\n    return key\n  }\n\n  if (isCryptoKey(key)) {\n    return key\n  }\n\n  if (isKeyObject(key)) {\n    if (key.type === 'secret') {\n      return (key as ConvertableKeyObject).export()\n    }\n\n    if ('toCryptoKey' in key && typeof key.toCryptoKey === 'function') {\n      try {\n        return handleKeyObject(key as ConvertableKeyObject, alg)\n      } catch (err) {\n        if (err instanceof TypeError) {\n          throw err\n        }\n      }\n    }\n\n    let jwk: types.JWK = (key as ConvertableKeyObject).export({ format: 'jwk' })\n    return handleJWK(key, jwk, alg)\n  }\n\n  if (isJWK(key)) {\n    if (key.k) {\n      return decode(key.k)\n    }\n    return handleJWK(key, key, alg, true)\n  }\n\n  throw new Error('unreachable')\n}\n"
  },
  {
    "path": "src/lib/pbes2kw.ts",
    "content": "import type * as types from '../types.d.ts'\nimport { encode as b64u } from '../util/base64url.js'\nimport * as aeskw from './aeskw.js'\nimport { checkEncCryptoKey } from './crypto_key.js'\nimport { concat, encode } from './buffer_utils.js'\nimport { JWEInvalid } from '../util/errors.js'\n\nfunction getCryptoKey(key: types.CryptoKey | Uint8Array, alg: string) {\n  if (key instanceof Uint8Array) {\n    return crypto.subtle.importKey('raw', key as Uint8Array<ArrayBuffer>, 'PBKDF2', false, [\n      'deriveBits',\n    ])\n  }\n\n  checkEncCryptoKey(key, alg, 'deriveBits')\n  return key\n}\n\nconst concatSalt = (alg: string, p2sInput: Uint8Array) =>\n  concat(encode(alg), Uint8Array.of(0x00), p2sInput)\n\nasync function deriveKey(\n  p2s: Uint8Array,\n  alg: string,\n  p2c: number,\n  key: types.CryptoKey | Uint8Array,\n) {\n  if (!(p2s instanceof Uint8Array) || p2s.length < 8) {\n    throw new JWEInvalid('PBES2 Salt Input must be 8 or more octets')\n  }\n\n  const salt = concatSalt(alg, p2s)\n  const keylen = parseInt(alg.slice(13, 16), 10)\n  const subtleAlg = {\n    hash: `SHA-${alg.slice(8, 11)}`,\n    iterations: p2c,\n    name: 'PBKDF2',\n    salt,\n  }\n\n  const cryptoKey = await getCryptoKey(key, alg)\n\n  return new Uint8Array(await crypto.subtle.deriveBits(subtleAlg, cryptoKey, keylen))\n}\n\nexport async function wrap(\n  alg: string,\n  key: types.CryptoKey | Uint8Array,\n  cek: Uint8Array,\n  p2c = 2048,\n  p2s: Uint8Array = crypto.getRandomValues(new Uint8Array(16)),\n) {\n  const derived = await deriveKey(p2s, alg, p2c, key)\n\n  const encryptedKey = await aeskw.wrap(alg.slice(-6), derived, cek)\n\n  return { encryptedKey, p2c, p2s: b64u(p2s) }\n}\n\nexport async function unwrap(\n  alg: string,\n  key: types.CryptoKey | Uint8Array,\n  encryptedKey: Uint8Array,\n  p2c: number,\n  p2s: Uint8Array,\n) {\n  const derived = await deriveKey(p2s, alg, p2c, key)\n\n  return aeskw.unwrap(alg.slice(-6), derived, encryptedKey)\n}\n"
  },
  {
    "path": "src/lib/rsaes.ts",
    "content": "import type * as types from '../types.d.ts'\nimport { checkEncCryptoKey } from './crypto_key.js'\nimport { checkKeyLength } from './signing.js'\nimport { JOSENotSupported } from '../util/errors.js'\n\nconst subtleAlgorithm = (alg: string) => {\n  switch (alg) {\n    case 'RSA-OAEP':\n    case 'RSA-OAEP-256':\n    case 'RSA-OAEP-384':\n    case 'RSA-OAEP-512':\n      return 'RSA-OAEP'\n    default:\n      throw new JOSENotSupported(\n        `alg ${alg} is not supported either by JOSE or your javascript runtime`,\n      )\n  }\n}\n\nexport async function encrypt(alg: string, key: types.CryptoKey, cek: Uint8Array) {\n  checkEncCryptoKey(key, alg, 'encrypt')\n  checkKeyLength(alg, key)\n\n  return new Uint8Array(\n    await crypto.subtle.encrypt(subtleAlgorithm(alg), key, cek as Uint8Array<ArrayBuffer>),\n  )\n}\n\nexport async function decrypt(alg: string, key: types.CryptoKey, encryptedKey: Uint8Array) {\n  checkEncCryptoKey(key, alg, 'decrypt')\n  checkKeyLength(alg, key)\n\n  return new Uint8Array(\n    await crypto.subtle.decrypt(subtleAlgorithm(alg), key, encryptedKey as Uint8Array<ArrayBuffer>),\n  )\n}\n"
  },
  {
    "path": "src/lib/signing.ts",
    "content": "import type * as types from '../types.d.ts'\nimport { JOSENotSupported } from '../util/errors.js'\nimport { checkSigCryptoKey } from './crypto_key.js'\nimport { invalidKeyInput } from './invalid_key_input.js'\n\nexport function checkKeyLength(alg: string, key: types.CryptoKey) {\n  if (alg.startsWith('RS') || alg.startsWith('PS')) {\n    const { modulusLength } = key.algorithm as RsaKeyAlgorithm\n    if (typeof modulusLength !== 'number' || modulusLength < 2048) {\n      throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`)\n    }\n  }\n}\n\nfunction subtleAlgorithm(alg: string, algorithm: KeyAlgorithm | EcKeyAlgorithm) {\n  const hash = `SHA-${alg.slice(-3)}`\n  switch (alg) {\n    case 'HS256':\n    case 'HS384':\n    case 'HS512':\n      return { hash, name: 'HMAC' }\n    case 'PS256':\n    case 'PS384':\n    case 'PS512':\n      return { hash, name: 'RSA-PSS', saltLength: parseInt(alg.slice(-3), 10) >> 3 }\n    case 'RS256':\n    case 'RS384':\n    case 'RS512':\n      return { hash, name: 'RSASSA-PKCS1-v1_5' }\n    case 'ES256':\n    case 'ES384':\n    case 'ES512':\n      return { hash, name: 'ECDSA', namedCurve: (algorithm as EcKeyAlgorithm).namedCurve }\n    case 'Ed25519': // Fall through\n    case 'EdDSA':\n      return { name: 'Ed25519' }\n    case 'ML-DSA-44':\n    case 'ML-DSA-65':\n    case 'ML-DSA-87':\n      return { name: alg }\n    default:\n      throw new JOSENotSupported(\n        `alg ${alg} is not supported either by JOSE or your javascript runtime`,\n      )\n  }\n}\n\nasync function getSigKey(alg: string, key: types.CryptoKey | Uint8Array, usage: KeyUsage) {\n  if (key instanceof Uint8Array) {\n    if (!alg.startsWith('HS')) {\n      throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'KeyObject', 'JSON Web Key'))\n    }\n    return crypto.subtle.importKey(\n      'raw',\n      key as Uint8Array<ArrayBuffer>,\n      { hash: `SHA-${alg.slice(-3)}`, name: 'HMAC' },\n      false,\n      [usage],\n    )\n  }\n\n  checkSigCryptoKey(key, alg, usage)\n  return key\n}\n\nexport async function sign(alg: string, key: types.CryptoKey | Uint8Array, data: Uint8Array) {\n  const cryptoKey = await getSigKey(alg, key, 'sign')\n  checkKeyLength(alg, cryptoKey)\n  const signature = await crypto.subtle.sign(\n    subtleAlgorithm(alg, cryptoKey.algorithm),\n    cryptoKey,\n    data as Uint8Array<ArrayBuffer>,\n  )\n  return new Uint8Array(signature)\n}\n\nexport async function verify(\n  alg: string,\n  key: types.CryptoKey | Uint8Array,\n  signature: Uint8Array,\n  data: Uint8Array,\n) {\n  const cryptoKey = await getSigKey(alg, key, 'verify')\n  checkKeyLength(alg, cryptoKey)\n  const algorithm = subtleAlgorithm(alg, cryptoKey.algorithm)\n  try {\n    return await crypto.subtle.verify(\n      algorithm,\n      cryptoKey,\n      signature as Uint8Array<ArrayBuffer>,\n      data as Uint8Array<ArrayBuffer>,\n    )\n  } catch {\n    return false\n  }\n}\n"
  },
  {
    "path": "src/lib/type_checks.ts",
    "content": "import type * as types from '../types.d.ts'\n\nconst isObjectLike = (value: unknown) => typeof value === 'object' && value !== null\n\nexport function isObject<T = object>(input: unknown): input is T {\n  if (!isObjectLike(input) || Object.prototype.toString.call(input) !== '[object Object]') {\n    return false\n  }\n  if (Object.getPrototypeOf(input) === null) {\n    return true\n  }\n  let proto = input\n  while (Object.getPrototypeOf(proto) !== null) {\n    proto = Object.getPrototypeOf(proto)\n  }\n  return Object.getPrototypeOf(input) === proto\n}\n\nexport function isDisjoint(...headers: Array<object | undefined>) {\n  const sources = headers.filter(Boolean) as object[]\n\n  if (sources.length === 0 || sources.length === 1) {\n    return true\n  }\n\n  let acc!: Set<string>\n  for (const header of sources) {\n    const parameters = Object.keys(header)\n    if (!acc || acc.size === 0) {\n      acc = new Set(parameters)\n      continue\n    }\n\n    for (const parameter of parameters) {\n      if (acc.has(parameter)) {\n        return false\n      }\n      acc.add(parameter)\n    }\n  }\n\n  return true\n}\n\nexport const isJWK = (key: unknown): key is types.JWK & { kty: string } =>\n  isObject<types.JWK>(key) && typeof key.kty === 'string'\n\nexport const isPrivateJWK = (key: types.JWK & { kty: string }) =>\n  key.kty !== 'oct' &&\n  ((key.kty === 'AKP' && typeof key.priv === 'string') || typeof key.d === 'string')\n\nexport const isPublicJWK = (key: types.JWK & { kty: string }) =>\n  key.kty !== 'oct' && key.d === undefined && key.priv === undefined\n\nexport const isSecretJWK = (key: types.JWK & { kty: string }) =>\n  key.kty === 'oct' && typeof key.k === 'string'\n"
  },
  {
    "path": "src/lib/validate_algorithms.ts",
    "content": "export function validateAlgorithms(option: string, algorithms?: string[]) {\n  if (\n    algorithms !== undefined &&\n    (!Array.isArray(algorithms) || algorithms.some((s) => typeof s !== 'string'))\n  ) {\n    throw new TypeError(`\"${option}\" option must be an array of strings`)\n  }\n\n  if (!algorithms) {\n    return undefined\n  }\n\n  return new Set(algorithms)\n}\n"
  },
  {
    "path": "src/lib/validate_crit.ts",
    "content": "import { JOSENotSupported, JWEInvalid, JWSInvalid } from '../util/errors.js'\n\ninterface CritCheckHeader {\n  b64?: boolean\n  crit?: string[]\n  [propName: string]: unknown\n}\n\nexport function validateCrit(\n  Err: typeof JWEInvalid | typeof JWSInvalid,\n  recognizedDefault: Map<string, boolean>,\n  recognizedOption: { [propName: string]: boolean } | undefined,\n  protectedHeader: CritCheckHeader | undefined,\n  joseHeader: CritCheckHeader,\n) {\n  if (joseHeader.crit !== undefined && protectedHeader?.crit === undefined) {\n    throw new Err('\"crit\" (Critical) Header Parameter MUST be integrity protected')\n  }\n\n  if (!protectedHeader || protectedHeader.crit === undefined) {\n    return new Set()\n  }\n\n  if (\n    !Array.isArray(protectedHeader.crit) ||\n    protectedHeader.crit.length === 0 ||\n    protectedHeader.crit.some((input: string) => typeof input !== 'string' || input.length === 0)\n  ) {\n    throw new Err(\n      '\"crit\" (Critical) Header Parameter MUST be an array of non-empty strings when present',\n    )\n  }\n\n  let recognized: Map<string, boolean>\n  if (recognizedOption !== undefined) {\n    recognized = new Map([...Object.entries(recognizedOption), ...recognizedDefault.entries()])\n  } else {\n    recognized = recognizedDefault\n  }\n\n  for (const parameter of protectedHeader.crit) {\n    if (!recognized.has(parameter)) {\n      throw new JOSENotSupported(`Extension Header Parameter \"${parameter}\" is not recognized`)\n    }\n\n    if (joseHeader[parameter] === undefined) {\n      throw new Err(`Extension Header Parameter \"${parameter}\" is missing`)\n    }\n    if (recognized.get(parameter) && protectedHeader[parameter] === undefined) {\n      throw new Err(`Extension Header Parameter \"${parameter}\" MUST be integrity protected`)\n    }\n  }\n\n  return new Set(protectedHeader.crit)\n}\n"
  },
  {
    "path": "src/types.d.ts",
    "content": "/** Generic JSON Web Key Parameters. */\nexport interface JWKParameters {\n  /** JWK \"kty\" (Key Type) Parameter */\n  kty?: string\n  /**\n   * JWK \"alg\" (Algorithm) Parameter\n   *\n   * @see {@link https://github.com/panva/jose/issues/210 Algorithm Key Requirements}\n   */\n  alg?: string\n  /** JWK \"key_ops\" (Key Operations) Parameter */\n  key_ops?: string[]\n  /** JWK \"ext\" (Extractable) Parameter */\n  ext?: boolean\n  /** JWK \"use\" (Public Key Use) Parameter */\n  use?: string\n  /** JWK \"x5c\" (X.509 Certificate Chain) Parameter */\n  x5c?: string[]\n  /** JWK \"x5t\" (X.509 Certificate SHA-1 Thumbprint) Parameter */\n  x5t?: string\n  /** JWK \"x5t#S256\" (X.509 Certificate SHA-256 Thumbprint) Parameter */\n  'x5t#S256'?: string\n  /** JWK \"x5u\" (X.509 URL) Parameter */\n  x5u?: string\n  /** JWK \"kid\" (Key ID) Parameter */\n  kid?: string\n}\n\n/** Convenience interface for Public OKP JSON Web Keys */\nexport interface JWK_OKP_Public extends JWKParameters {\n  /** OKP JWK \"crv\" (The Subtype of Key Pair) Parameter */\n  crv: string\n  /** OKP JWK \"x\" (The public key) Parameter */\n  x: string\n}\n\n/** Convenience interface for Private OKP JSON Web Keys */\nexport interface JWK_OKP_Private extends JWK_OKP_Public {\n  /** OKP JWK \"d\" (The Private Key) Parameter */\n  d: string\n}\n\n/** Convenience interface for Public AKP JSON Web Keys */\nexport interface JWK_AKP_Public extends JWKParameters {\n  /** JWK \"alg\" (Algorithm) Parameter */\n  alg: string\n  /** AKP JWK \"pub\" (The Public key) Parameter */\n  pub: string\n}\n\n/** Convenience interface for Private AKP JSON Web Keys */\nexport interface JWK_AKP_Private extends JWK_AKP_Public {\n  /** AKP JWK \"priv\" (The Private Key) Parameter */\n  priv: string\n}\n\n/** Convenience interface for Public EC JSON Web Keys */\nexport interface JWK_EC_Public extends JWKParameters {\n  /** EC JWK \"crv\" (Curve) Parameter */\n  crv: string\n  /** EC JWK \"x\" (X Coordinate) Parameter */\n  x: string\n  /** EC JWK \"y\" (Y Coordinate) Parameter */\n  y: string\n}\n\n/** Convenience interface for Private EC JSON Web Keys */\nexport interface JWK_EC_Private extends JWK_EC_Public {\n  /** EC JWK \"d\" (ECC Private Key) Parameter */\n  d: string\n}\n\n/** Convenience interface for Public RSA JSON Web Keys */\nexport interface JWK_RSA_Public extends JWKParameters {\n  /** RSA JWK \"e\" (Exponent) Parameter */\n  e: string\n  /** RSA JWK \"n\" (Modulus) Parameter */\n  n: string\n}\n\n/** Convenience interface for Private RSA JSON Web Keys */\nexport interface JWK_RSA_Private extends JWK_RSA_Public {\n  /** RSA JWK \"d\" (Private Exponent) Parameter */\n  d: string\n  /** RSA JWK \"dp\" (First Factor CRT Exponent) Parameter */\n  dp: string\n  /** RSA JWK \"dq\" (Second Factor CRT Exponent) Parameter */\n  dq: string\n  /** RSA JWK \"p\" (First Prime Factor) Parameter */\n  p: string\n  /** RSA JWK \"q\" (Second Prime Factor) Parameter */\n  q: string\n  /** RSA JWK \"qi\" (First CRT Coefficient) Parameter */\n  qi: string\n}\n\n/** Convenience interface for oct JSON Web Keys */\nexport interface JWK_oct extends JWKParameters {\n  /** Oct JWK \"k\" (Key Value) Parameter */\n  k: string\n}\n\n/**\n * JSON Web Key ({@link https://www.rfc-editor.org/rfc/rfc7517 JWK}). \"RSA\", \"EC\", \"OKP\", \"AKP\", and\n * \"oct\" key types are supported.\n *\n * @see {@link JWK_AKP_Public}\n * @see {@link JWK_AKP_Private}\n * @see {@link JWK_OKP_Public}\n * @see {@link JWK_OKP_Private}\n * @see {@link JWK_EC_Public}\n * @see {@link JWK_EC_Private}\n * @see {@link JWK_RSA_Public}\n * @see {@link JWK_RSA_Private}\n * @see {@link JWK_oct}\n */\nexport interface JWK extends JWKParameters {\n  /**\n   * - EC JWK \"crv\" (Curve) Parameter\n   * - OKP JWK \"crv\" (The Subtype of Key Pair) Parameter\n   */\n  crv?: string\n  /**\n   * - Private RSA JWK \"d\" (Private Exponent) Parameter\n   * - Private EC JWK \"d\" (ECC Private Key) Parameter\n   * - Private OKP JWK \"d\" (The Private Key) Parameter\n   */\n  d?: string\n  /** Private RSA JWK \"dp\" (First Factor CRT Exponent) Parameter */\n  dp?: string\n  /** Private RSA JWK \"dq\" (Second Factor CRT Exponent) Parameter */\n  dq?: string\n  /** RSA JWK \"e\" (Exponent) Parameter */\n  e?: string\n  /** Oct JWK \"k\" (Key Value) Parameter */\n  k?: string\n  /** RSA JWK \"n\" (Modulus) Parameter */\n  n?: string\n  /** Private RSA JWK \"p\" (First Prime Factor) Parameter */\n  p?: string\n  /** Private RSA JWK \"q\" (Second Prime Factor) Parameter */\n  q?: string\n  /** Private RSA JWK \"qi\" (First CRT Coefficient) Parameter */\n  qi?: string\n  /**\n   * - EC JWK \"x\" (X Coordinate) Parameter\n   * - OKP JWK \"x\" (The public key) Parameter\n   */\n  x?: string\n  /** EC JWK \"y\" (Y Coordinate) Parameter */\n  y?: string\n  /** AKP JWK \"pub\" (Public Key) Parameter */\n  pub?: string\n  /** AKP JWK \"priv\" (Private key) Parameter */\n  priv?: string\n}\n\n/**\n * @private\n *\n * @internal\n */\nexport interface GenericGetKeyFunction<IProtectedHeader, IToken, ReturnKeyTypes> {\n  /**\n   * Dynamic key resolution function. No token components have been verified at the time of this\n   * function call.\n   *\n   * If a suitable key for the token cannot be matched, throw an error instead.\n   *\n   * @param protectedHeader JWE or JWS Protected Header.\n   * @param token The consumed JWE or JWS token.\n   */\n  (protectedHeader: IProtectedHeader, token: IToken): Promise<ReturnKeyTypes> | ReturnKeyTypes\n}\n\n/**\n * Generic Interface for consuming operations dynamic key resolution.\n *\n * @param IProtectedHeader Type definition of the JWE or JWS Protected Header.\n * @param IToken Type definition of the consumed JWE or JWS token.\n */\nexport interface GetKeyFunction<IProtectedHeader, IToken> extends GenericGetKeyFunction<\n  IProtectedHeader,\n  IToken,\n  CryptoKey | KeyObject | JWK | Uint8Array\n> {}\n\n/**\n * Flattened JWS definition for verify function inputs, allows payload as {@link !Uint8Array} for\n * detached signature validation.\n */\nexport interface FlattenedJWSInput {\n  /**\n   * The \"header\" member MUST be present and contain the value JWS Unprotected Header when the JWS\n   * Unprotected Header value is non- empty; otherwise, it MUST be absent. This value is represented\n   * as an unencoded JSON object, rather than as a string. These Header Parameter values are not\n   * integrity protected.\n   */\n  header?: JWSHeaderParameters\n\n  /**\n   * The \"payload\" member MUST be present and contain the value BASE64URL(JWS Payload). When RFC7797\n   * \"b64\": false is used the value passed may also be a {@link !Uint8Array}.\n   */\n  payload: string | Uint8Array\n\n  /**\n   * The \"protected\" member MUST be present and contain the value BASE64URL(UTF8(JWS Protected\n   * Header)) when the JWS Protected Header value is non-empty; otherwise, it MUST be absent. These\n   * Header Parameter values are integrity protected.\n   */\n  protected?: string\n\n  /** The \"signature\" member MUST be present and contain the value BASE64URL(JWS Signature). */\n  signature: string\n}\n\n/**\n * General JWS definition for verify function inputs, allows payload as {@link !Uint8Array} for\n * detached signature validation.\n */\nexport interface GeneralJWSInput {\n  /**\n   * The \"payload\" member MUST be present and contain the value BASE64URL(JWS Payload). When when\n   * JWS Unencoded Payload ({@link https://www.rfc-editor.org/rfc/rfc7797 RFC7797}) \"b64\": false is\n   * used the value passed may also be a {@link !Uint8Array}.\n   */\n  payload: string | Uint8Array\n\n  /**\n   * The \"signatures\" member value MUST be an array of JSON objects. Each object represents a\n   * signature or MAC over the JWS Payload and the JWS Protected Header.\n   */\n  signatures: Omit<FlattenedJWSInput, 'payload'>[]\n}\n\n/**\n * Flattened JWS JSON Serialization Syntax token. Payload is returned as an empty string when JWS\n * Unencoded Payload ({@link https://www.rfc-editor.org/rfc/rfc7797 RFC7797}) is used.\n */\nexport interface FlattenedJWS extends Partial<FlattenedJWSInput> {\n  payload: string\n  signature: string\n}\n\n/**\n * General JWS JSON Serialization Syntax token. Payload is returned as an empty string when JWS\n * Unencoded Payload ({@link https://www.rfc-editor.org/rfc/rfc7797 RFC7797}) is used.\n */\nexport interface GeneralJWS {\n  payload: string\n  signatures: Omit<FlattenedJWSInput, 'payload'>[]\n}\n\n/** Header Parameters common to JWE and JWS */\nexport interface JoseHeaderParameters {\n  /** \"kid\" (Key ID) Header Parameter */\n  kid?: string\n\n  /** \"x5t\" (X.509 Certificate SHA-1 Thumbprint) Header Parameter */\n  x5t?: string\n\n  /** \"x5c\" (X.509 Certificate Chain) Header Parameter */\n  x5c?: string[]\n\n  /** \"x5u\" (X.509 URL) Header Parameter */\n  x5u?: string\n\n  /** \"jku\" (JWK Set URL) Header Parameter */\n  jku?: string\n\n  /** \"jwk\" (JSON Web Key) Header Parameter */\n  jwk?: Pick<JWK, 'kty' | 'crv' | 'x' | 'y' | 'e' | 'n' | 'alg' | 'pub'>\n\n  /** \"typ\" (Type) Header Parameter */\n  typ?: string\n\n  /** \"cty\" (Content Type) Header Parameter */\n  cty?: string\n}\n\n/** Recognized JWS Header Parameters, any other Header Members may also be present. */\nexport interface JWSHeaderParameters extends JoseHeaderParameters {\n  /**\n   * JWS \"alg\" (Algorithm) Header Parameter\n   *\n   * @see {@link https://github.com/panva/jose/issues/210#jws-alg Algorithm Key Requirements}\n   */\n  alg?: string\n\n  /**\n   * This JWS Extension Header Parameter modifies the JWS Payload representation and the JWS Signing\n   * Input computation as per {@link https://www.rfc-editor.org/rfc/rfc7797 RFC7797}.\n   */\n  b64?: boolean\n\n  /** JWS \"crit\" (Critical) Header Parameter */\n  crit?: string[]\n\n  /** Any other JWS Header member. */\n  [propName: string]: unknown\n}\n\n/** Recognized JWE Key Management-related Header Parameters. */\nexport interface JWEKeyManagementHeaderParameters {\n  /**\n   * ECDH-ES \"apu\" (Agreement PartyUInfo). This will be used as a JOSE Header Parameter and will be\n   * used in ECDH's ConcatKDF.\n   */\n  apu?: Uint8Array\n\n  /**\n   * ECDH-ES \"apv\" (Agreement PartyVInfo). This will be used as a JOSE Header Parameter and will be\n   * used in ECDH's ConcatKDF.\n   */\n  apv?: Uint8Array\n  /**\n   * @deprecated You should not use this parameter. It is only intended for testing and vector\n   *   validation purposes.\n   */\n  p2c?: number\n  /**\n   * @deprecated You should not use this parameter. It is only intended for testing and vector\n   *   validation purposes.\n   */\n  p2s?: Uint8Array\n  /**\n   * @deprecated You should not use this parameter. It is only intended for testing and vector\n   *   validation purposes.\n   */\n  iv?: Uint8Array\n  /**\n   * @deprecated You should not use this parameter. It is only intended for testing and vector\n   *   validation purposes.\n   */\n  epk?: CryptoKey | KeyObject\n}\n\n/** Flattened JWE JSON Serialization Syntax token. */\nexport interface FlattenedJWE {\n  /**\n   * The \"aad\" member MUST be present and contain the value BASE64URL(JWE AAD)) when the JWE AAD\n   * value is non-empty; otherwise, it MUST be absent. A JWE AAD value can be included to supply a\n   * base64url-encoded value to be integrity protected but not encrypted.\n   */\n  aad?: string\n\n  /** The \"ciphertext\" member MUST be present and contain the value BASE64URL(JWE Ciphertext). */\n  ciphertext: string\n\n  /**\n   * The \"encrypted_key\" member MUST be present and contain the value BASE64URL(JWE Encrypted Key)\n   * when the JWE Encrypted Key value is non-empty; otherwise, it MUST be absent.\n   */\n  encrypted_key?: string\n\n  /**\n   * The \"header\" member MUST be present and contain the value JWE Per- Recipient Unprotected Header\n   * when the JWE Per-Recipient Unprotected Header value is non-empty; otherwise, it MUST be absent.\n   * This value is represented as an unencoded JSON object, rather than as a string. These Header\n   * Parameter values are not integrity protected.\n   */\n  header?: JWEHeaderParameters\n\n  /**\n   * The \"iv\" member MUST be present and contain the value BASE64URL(JWE Initialization Vector) when\n   * the JWE Initialization Vector value is non-empty; otherwise, it MUST be absent.\n   */\n  iv?: string\n\n  /**\n   * The \"protected\" member MUST be present and contain the value BASE64URL(UTF8(JWE Protected\n   * Header)) when the JWE Protected Header value is non-empty; otherwise, it MUST be absent. These\n   * Header Parameter values are integrity protected.\n   */\n  protected?: string\n\n  /**\n   * The \"tag\" member MUST be present and contain the value BASE64URL(JWE Authentication Tag) when\n   * the JWE Authentication Tag value is non-empty; otherwise, it MUST be absent.\n   */\n  tag?: string\n\n  /**\n   * The \"unprotected\" member MUST be present and contain the value JWE Shared Unprotected Header\n   * when the JWE Shared Unprotected Header value is non-empty; otherwise, it MUST be absent. This\n   * value is represented as an unencoded JSON object, rather than as a string. These Header\n   * Parameter values are not integrity protected.\n   */\n  unprotected?: JWEHeaderParameters\n}\n\n/** General JWE JSON Serialization Syntax token. */\nexport interface GeneralJWE extends Omit<FlattenedJWE, 'encrypted_key' | 'header'> {\n  recipients: Pick<FlattenedJWE, 'encrypted_key' | 'header'>[]\n}\n\n/** Recognized JWE Header Parameters, any other Header members may also be present. */\nexport interface JWEHeaderParameters extends JoseHeaderParameters {\n  /**\n   * JWE \"alg\" (Algorithm) Header Parameter\n   *\n   * @see {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}\n   */\n  alg?: string\n\n  /**\n   * JWE \"enc\" (Encryption Algorithm) Header Parameter\n   *\n   * @see {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}\n   */\n  enc?: string\n\n  /** JWE \"crit\" (Critical) Header Parameter */\n  crit?: string[]\n\n  /**\n   * JWE \"zip\" (Compression Algorithm) Header Parameter.\n   *\n   * The only supported value is `\"DEF\"` (DEFLATE). Requires the `CompressionStream` /\n   * `DecompressionStream` APIs to be available in the runtime.\n   *\n   * @see {@link https://www.rfc-editor.org/rfc/rfc7516#section-4.1.3 JWE \"zip\" Header Parameter}\n   */\n  zip?: string\n\n  /** Any other JWE Header member. */\n  [propName: string]: unknown\n}\n\n/** Shared Interface with a \"crit\" property for all sign, verify, encrypt and decrypt operations. */\nexport interface CritOption {\n  /**\n   * An object with keys representing recognized \"crit\" (Critical) Header Parameter names. The value\n   * for those is either `true` or `false`. `true` when the Header Parameter MUST be integrity\n   * protected, `false` when it's irrelevant.\n   *\n   * This makes the \"Extension Header Parameter \"...\" is not recognized\" error go away.\n   *\n   * Use this when a given JWS/JWT/JWE profile requires the use of proprietary non-registered \"crit\"\n   * (Critical) Header Parameters. This will only make sure the Header Parameter is syntactically\n   * correct when provided and that it is optionally integrity protected. It will not process the\n   * Header Parameter in any way or reject the operation if it is missing. You MUST still verify the\n   * Header Parameter was present and process it according to the profile's validation steps after\n   * the operation succeeds.\n   *\n   * The JWS extension Header Parameter `b64` is always recognized and processed properly. No other\n   * registered Header Parameters that need this kind of default built-in treatment are currently\n   * available.\n   */\n  crit?: {\n    [propName: string]: boolean\n  }\n}\n\n/** JWE Decryption options. */\nexport interface DecryptOptions extends CritOption {\n  /**\n   * A list of accepted JWE \"alg\" (Algorithm) Header Parameter values. By default all \"alg\"\n   * (Algorithm) Header Parameter values applicable for the used key/secret are allowed except for\n   * all PBES2 Key Management Algorithms, these need to be explicitly allowed using this option.\n   */\n  keyManagementAlgorithms?: string[]\n\n  /**\n   * A list of accepted JWE \"enc\" (Encryption Algorithm) Header Parameter values. By default all\n   * \"enc\" (Encryption Algorithm) values applicable for the used key/secret are allowed.\n   */\n  contentEncryptionAlgorithms?: string[]\n\n  /**\n   * (PBES2 Key Management Algorithms only) Maximum allowed \"p2c\" (PBES2 Count) Header Parameter\n   * value. The PBKDF2 iteration count defines the algorithm's computational expense. By default\n   * this value is set to 10000.\n   */\n  maxPBES2Count?: number\n\n  /**\n   * Maximum allowed size (in bytes) of the decompressed plaintext when the JWE `\"zip\"` (Compression\n   * Algorithm) Header Parameter is present. By default this value is set to 250000 (250 KB). The\n   * value must be `0`, a positive safe integer, or `Infinity`.\n   *\n   * Set to `0` to reject all compressed JWEs during decryption.\n   *\n   * Set to `Infinity` to disable the decompressed size limit.\n   */\n  maxDecompressedLength?: number\n}\n\n/** JWE Encryption options. */\nexport interface EncryptOptions extends CritOption {}\n\n/** JWT Claims Set verification options. */\nexport interface JWTClaimVerificationOptions {\n  /**\n   * Expected JWT \"aud\" (Audience) Claim value(s).\n   *\n   * This option makes the JWT \"aud\" (Audience) Claim presence required.\n   */\n  audience?: string | string[]\n\n  /**\n   * Clock skew tolerance\n   *\n   * - In seconds when number (e.g. 5)\n   * - Resolved into a number of seconds when a string (e.g. \"5 seconds\", \"10 minutes\", \"2 hours\").\n   *\n   * Used when validating the JWT \"nbf\" (Not Before) and \"exp\" (Expiration Time) claims, and when\n   * validating the \"iat\" (Issued At) claim if the {@link maxTokenAge `maxTokenAge` option} is set.\n   */\n  clockTolerance?: string | number\n\n  /**\n   * Expected JWT \"iss\" (Issuer) Claim value(s).\n   *\n   * This option makes the JWT \"iss\" (Issuer) Claim presence required.\n   */\n  issuer?: string | string[]\n\n  /**\n   * Maximum time elapsed (in seconds) from the JWT \"iat\" (Issued At) Claim value.\n   *\n   * - In seconds when number (e.g. 5)\n   * - Resolved into a number of seconds when a string (e.g. \"5 seconds\", \"10 minutes\", \"2 hours\").\n   *\n   * This option makes the JWT \"iat\" (Issued At) Claim presence required.\n   */\n  maxTokenAge?: string | number\n\n  /**\n   * Expected JWT \"sub\" (Subject) Claim value.\n   *\n   * This option makes the JWT \"sub\" (Subject) Claim presence required.\n   */\n  subject?: string\n\n  /**\n   * Expected JWT \"typ\" (Type) Header Parameter value.\n   *\n   * This option makes the JWT \"typ\" (Type) Header Parameter presence required.\n   */\n  typ?: string\n\n  /** Date to use when comparing NumericDate claims, defaults to `new Date()`. */\n  currentDate?: Date\n\n  /**\n   * Array of required Claim Names that must be present in the JWT Claims Set. Default is that: if\n   * the {@link issuer `issuer` option} is set, then JWT \"iss\" (Issuer) Claim must be present; if the\n   * {@link audience `audience` option} is set, then JWT \"aud\" (Audience) Claim must be present; if\n   * the {@link subject `subject` option} is set, then JWT \"sub\" (Subject) Claim must be present; if\n   * the {@link maxTokenAge `maxTokenAge` option} is set, then JWT \"iat\" (Issued At) Claim must be\n   * present.\n   */\n  requiredClaims?: string[]\n}\n\n/** JWS Verification options. */\nexport interface VerifyOptions extends CritOption {\n  /**\n   * A list of accepted JWS \"alg\" (Algorithm) Header Parameter values. By default all \"alg\"\n   * (Algorithm) values applicable for the used key/secret are allowed.\n   *\n   * > [!NOTE]\\\n   * > Unsecured JWTs (`{ \"alg\": \"none\" }`) are never accepted by this API.\n   */\n  algorithms?: string[]\n}\n\n/** JWS Signing options. */\nexport interface SignOptions extends CritOption {}\n\n/** Recognized JWT Claims Set members, any other members may also be present. */\nexport interface JWTPayload {\n  /**\n   * JWT Issuer\n   *\n   * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.1 RFC7519#section-4.1.1}\n   */\n  iss?: string\n\n  /**\n   * JWT Subject\n   *\n   * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.2 RFC7519#section-4.1.2}\n   */\n  sub?: string\n\n  /**\n   * JWT Audience\n   *\n   * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.3 RFC7519#section-4.1.3}\n   */\n  aud?: string | string[]\n\n  /**\n   * JWT ID\n   *\n   * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.7 RFC7519#section-4.1.7}\n   */\n  jti?: string\n\n  /**\n   * JWT Not Before\n   *\n   * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.5 RFC7519#section-4.1.5}\n   */\n  nbf?: number\n\n  /**\n   * JWT Expiration Time\n   *\n   * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.4 RFC7519#section-4.1.4}\n   */\n  exp?: number\n\n  /**\n   * JWT Issued At\n   *\n   * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6 RFC7519#section-4.1.6}\n   */\n  iat?: number\n\n  /** Any other JWT Claim Set member. */\n  [propName: string]: unknown\n}\n\n/** Flattened JWE JSON Serialization Syntax decryption result */\nexport interface FlattenedDecryptResult {\n  /** JWE AAD. */\n  additionalAuthenticatedData?: Uint8Array\n\n  /** Plaintext. */\n  plaintext: Uint8Array\n\n  /** JWE Protected Header. */\n  protectedHeader?: JWEHeaderParameters\n\n  /** JWE Shared Unprotected Header. */\n  sharedUnprotectedHeader?: JWEHeaderParameters\n\n  /** JWE Per-Recipient Unprotected Header. */\n  unprotectedHeader?: JWEHeaderParameters\n}\n\n/** General JWE JSON Serialization Syntax decryption result */\nexport interface GeneralDecryptResult extends FlattenedDecryptResult {}\n\n/** Compact JWE decryption result */\nexport interface CompactDecryptResult {\n  /** Plaintext. */\n  plaintext: Uint8Array\n\n  /** JWE Protected Header. */\n  protectedHeader: CompactJWEHeaderParameters\n}\n\n/** Flattened JWS JSON Serialization Syntax verification result */\nexport interface FlattenedVerifyResult {\n  /** JWS Payload. */\n  payload: Uint8Array\n\n  /** JWS Protected Header. */\n  protectedHeader?: JWSHeaderParameters\n\n  /** JWS Unprotected Header. */\n  unprotectedHeader?: JWSHeaderParameters\n}\n\n/** General JWS JSON Serialization Syntax verification result */\nexport interface GeneralVerifyResult extends FlattenedVerifyResult {}\n\n/** Compact JWS verification result */\nexport interface CompactVerifyResult {\n  /** JWS Payload. */\n  payload: Uint8Array\n\n  /** JWS Protected Header. */\n  protectedHeader: CompactJWSHeaderParameters\n}\n\n/** Signed JSON Web Token (JWT) verification result */\nexport interface JWTVerifyResult<PayloadType = JWTPayload> {\n  /** JWT Claims Set. */\n  payload: PayloadType & JWTPayload\n\n  /** JWS Protected Header. */\n  protectedHeader: JWTHeaderParameters\n}\n\n/** Encrypted JSON Web Token (JWT) decryption result */\nexport interface JWTDecryptResult<PayloadType = JWTPayload> {\n  /** JWT Claims Set. */\n  payload: PayloadType & JWTPayload\n\n  /** JWE Protected Header. */\n  protectedHeader: CompactJWEHeaderParameters\n}\n\n/** When key resolver functions are used this becomes part of successful resolves */\nexport interface ResolvedKey {\n  /** Key resolved from the key resolver function. */\n  key: CryptoKey | Uint8Array\n}\n\n/** Recognized Compact JWS Header Parameters, any other Header Members may also be present. */\nexport interface CompactJWSHeaderParameters extends JWSHeaderParameters {\n  alg: string\n}\n\n/** Recognized Signed JWT Header Parameters, any other Header Members may also be present. */\nexport interface JWTHeaderParameters extends CompactJWSHeaderParameters {\n  b64?: true\n}\n\n/** Recognized Compact JWE Header Parameters, any other Header Members may also be present. */\nexport interface CompactJWEHeaderParameters extends JWEHeaderParameters {\n  alg: string\n  enc: string\n}\n\n/** JSON Web Key Set */\nexport interface JSONWebKeySet {\n  keys: JWK[]\n}\n\n/**\n * {@link !KeyObject} is a representation of a key/secret available in the Node.js runtime. You may\n * use the Node.js runtime APIs {@link !createPublicKey}, {@link !createPrivateKey}, and\n * {@link !createSecretKey} to obtain a {@link !KeyObject} from your existing key material.\n */\nexport interface KeyObject {\n  type: string\n}\n\n/**\n * {@link !CryptoKey} is a representation of a key/secret available in all supported runtimes. In\n * addition to the {@link key/import Key Import Functions} you may use the\n * {@link !SubtleCrypto.importKey} API to obtain a {@link !CryptoKey} from your existing key\n * material.\n */\nexport type CryptoKey = Extract<\n  Awaited<ReturnType<typeof crypto.subtle.generateKey>>,\n  { type: string }\n>\n\n/** Generic interface for JWT producing classes. */\nexport interface ProduceJWT {\n  /**\n   * Set the \"iss\" (Issuer) Claim.\n   *\n   * @param issuer \"Issuer\" Claim value to set on the JWT Claims Set.\n   */\n  setIssuer(issuer: string): this\n\n  /**\n   * Set the \"sub\" (Subject) Claim.\n   *\n   * @param subject \"sub\" (Subject) Claim value to set on the JWT Claims Set.\n   */\n  setSubject(subject: string): this\n\n  /**\n   * Set the \"aud\" (Audience) Claim.\n   *\n   * @param audience \"aud\" (Audience) Claim value to set on the JWT Claims Set.\n   */\n  setAudience(audience: string | string[]): this\n\n  /**\n   * Set the \"jti\" (JWT ID) Claim.\n   *\n   * @param jwtId \"jti\" (JWT ID) Claim value to set on the JWT Claims Set.\n   */\n  setJti(jwtId: string): this\n\n  /**\n   * Set the \"nbf\" (Not Before) Claim.\n   *\n   * - If a `number` is passed as an argument it is used as the claim directly.\n   * - If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n   *   claim.\n   * - If a `string` is passed as an argument it is resolved to a time span, and then added to the\n   *   current unix timestamp and used as the claim.\n   *\n   * Format used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\n   * day\".\n   *\n   * Valid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n   * \"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n   * \"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\n   * alias for a year.\n   *\n   * If the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\n   * subtracted from the current unix timestamp. A \"from now\" suffix can also be used for\n   * readability when adding to the current unix timestamp.\n   *\n   * @param input \"nbf\" (Not Before) Claim value to set on the JWT Claims Set.\n   */\n  setNotBefore(input: number | string | Date): this\n\n  /**\n   * Set the \"exp\" (Expiration Time) Claim.\n   *\n   * - If a `number` is passed as an argument it is used as the claim directly.\n   * - If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n   *   claim.\n   * - If a `string` is passed as an argument it is resolved to a time span, and then added to the\n   *   current unix timestamp and used as the claim.\n   *\n   * Format used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\n   * day\".\n   *\n   * Valid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n   * \"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n   * \"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\n   * alias for a year.\n   *\n   * If the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\n   * subtracted from the current unix timestamp. A \"from now\" suffix can also be used for\n   * readability when adding to the current unix timestamp.\n   *\n   * @param input \"exp\" (Expiration Time) Claim value to set on the JWT Claims Set.\n   */\n  setExpirationTime(input: number | string | Date): this\n\n  /**\n   * Set the \"iat\" (Issued At) Claim.\n   *\n   * - If no argument is used the current unix timestamp is used as the claim.\n   * - If a `number` is passed as an argument it is used as the claim directly.\n   * - If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the\n   *   claim.\n   * - If a `string` is passed as an argument it is resolved to a time span, and then added to the\n   *   current unix timestamp and used as the claim.\n   *\n   * Format used for time span should be a number followed by a unit, such as \"5 minutes\" or \"1\n   * day\".\n   *\n   * Valid units are: \"sec\", \"secs\", \"second\", \"seconds\", \"s\", \"minute\", \"minutes\", \"min\", \"mins\",\n   * \"m\", \"hour\", \"hours\", \"hr\", \"hrs\", \"h\", \"day\", \"days\", \"d\", \"week\", \"weeks\", \"w\", \"year\",\n   * \"years\", \"yr\", \"yrs\", and \"y\". It is not possible to specify months. 365.25 days is used as an\n   * alias for a year.\n   *\n   * If the string is suffixed with \"ago\", or prefixed with a \"-\", the resulting time span gets\n   * subtracted from the current unix timestamp. A \"from now\" suffix can also be used for\n   * readability when adding to the current unix timestamp.\n   *\n   * @param input \"iat\" (Expiration Time) Claim value to set on the JWT Claims Set.\n   */\n  setIssuedAt(input?: number | string | Date): this\n}\n"
  },
  {
    "path": "src/util/base64url.ts",
    "content": "/**\n * Base64URL encoding and decoding utilities\n *\n * @module\n */\n\nimport { encoder, decoder } from '../lib/buffer_utils.js'\nimport { encodeBase64, decodeBase64 } from '../lib/base64.js'\n\n/** Decodes a Base64URL encoded input. */\nexport function decode(input: Uint8Array | string): Uint8Array {\n  // @ts-ignore\n  if (Uint8Array.fromBase64) {\n    // @ts-ignore\n    return Uint8Array.fromBase64(typeof input === 'string' ? input : decoder.decode(input), {\n      alphabet: 'base64url',\n    })\n  }\n\n  let encoded = input\n  if (encoded instanceof Uint8Array) {\n    encoded = decoder.decode(encoded)\n  }\n  encoded = encoded.replace(/-/g, '+').replace(/_/g, '/')\n  try {\n    return decodeBase64(encoded)\n  } catch {\n    throw new TypeError('The input to be decoded is not correctly encoded.')\n  }\n}\n\n/** Encodes an input using Base64URL with no padding. */\nexport function encode(input: Uint8Array | string): string {\n  let unencoded = input\n  if (typeof unencoded === 'string') {\n    unencoded = encoder.encode(unencoded)\n  }\n\n  // @ts-ignore\n  if (Uint8Array.prototype.toBase64) {\n    // @ts-ignore\n    return unencoded.toBase64({ alphabet: 'base64url', omitPadding: true })\n  }\n\n  return encodeBase64(unencoded).replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_')\n}\n"
  },
  {
    "path": "src/util/decode_jwt.ts",
    "content": "/**\n * JSON Web Token (JWT) Claims Set Decoding (no validation, no signature checking)\n *\n * @module\n */\n\nimport { decode as b64u } from './base64url.js'\nimport { decoder } from '../lib/buffer_utils.js'\nimport { isObject } from '../lib/type_checks.js'\nimport type * as types from '../types.d.ts'\nimport { JWTInvalid } from './errors.js'\n\n/**\n * Decodes a signed JSON Web Token payload. This does not validate the JWT Claims Set types or\n * values. This does not validate the JWS Signature. For a proper Signed JWT Claims Set validation\n * and JWS signature verification use `jose.jwtVerify()`. For an encrypted JWT Claims Set validation\n * and JWE decryption use `jose.jwtDecrypt()`.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/jwt/decode'`.\n *\n * @example\n *\n * ```js\n * const claims = jose.decodeJwt(token)\n * console.log(claims)\n * ```\n *\n * @param jwt JWT token in compact JWS serialization.\n */\nexport function decodeJwt<PayloadType = types.JWTPayload>(\n  jwt: string,\n): PayloadType & types.JWTPayload {\n  if (typeof jwt !== 'string')\n    throw new JWTInvalid('JWTs must use Compact JWS serialization, JWT must be a string')\n\n  const { 1: payload, length } = jwt.split('.')\n\n  if (length === 5) throw new JWTInvalid('Only JWTs using Compact JWS serialization can be decoded')\n  if (length !== 3) throw new JWTInvalid('Invalid JWT')\n  if (!payload) throw new JWTInvalid('JWTs must contain a payload')\n\n  let decoded: Uint8Array\n  try {\n    decoded = b64u(payload)\n  } catch {\n    throw new JWTInvalid('Failed to base64url decode the payload')\n  }\n\n  let result: unknown\n  try {\n    result = JSON.parse(decoder.decode(decoded))\n  } catch {\n    throw new JWTInvalid('Failed to parse the decoded payload as JSON')\n  }\n\n  if (!isObject<PayloadType & types.JWTPayload>(result))\n    throw new JWTInvalid('Invalid JWT Claims Set')\n\n  return result\n}\n"
  },
  {
    "path": "src/util/decode_protected_header.ts",
    "content": "/**\n * JOSE Protected Header Decoding (JWE, JWS, all serialization syntaxes)\n *\n * @module\n */\n\nimport { decode as b64u } from './base64url.js'\nimport { decoder } from '../lib/buffer_utils.js'\nimport { isObject } from '../lib/type_checks.js'\nimport type * as types from '../types.d.ts'\n\n/** JWE and JWS Header Parameters */\nexport type ProtectedHeaderParameters = types.JWSHeaderParameters & types.JWEHeaderParameters\n\n/**\n * Decodes the Protected Header of a JWE/JWS/JWT token utilizing any JOSE serialization.\n *\n * This function is exported (as a named export) from the main `'jose'` module entry point as well\n * as from its subpath export `'jose/decode/protected_header'`.\n *\n * @example\n *\n * ```js\n * const protectedHeader = jose.decodeProtectedHeader(token)\n * console.log(protectedHeader)\n * ```\n *\n * @param token JWE/JWS/JWT token in any JOSE serialization.\n */\nexport function decodeProtectedHeader(token: string | object): ProtectedHeaderParameters {\n  let protectedB64u!: unknown\n\n  if (typeof token === 'string') {\n    const parts = token.split('.')\n    if (parts.length === 3 || parts.length === 5) {\n      ;[protectedB64u] = parts\n    }\n  } else if (typeof token === 'object' && token) {\n    if ('protected' in token) {\n      protectedB64u = token.protected\n    } else {\n      throw new TypeError('Token does not contain a Protected Header')\n    }\n  }\n\n  try {\n    if (typeof protectedB64u !== 'string' || !protectedB64u) {\n      throw new Error()\n    }\n    const result = JSON.parse(decoder.decode(b64u(protectedB64u!)))\n    if (!isObject(result)) {\n      throw new Error()\n    }\n    return result as ProtectedHeaderParameters\n  } catch {\n    throw new TypeError('Invalid Token or Protected Header formatting')\n  }\n}\n"
  },
  {
    "path": "src/util/errors.ts",
    "content": "/**\n * JOSE module errors and error codes\n *\n * @module\n */\n\nimport type * as types from '../types.d.ts'\n\n/**\n * A generic Error that all other JOSE specific Error subclasses extend.\n *\n * @example\n *\n * Checking thrown error is a JOSE one\n *\n * ```js\n * if (err instanceof jose.errors.JOSEError) {\n *   // ...\n * }\n * ```\n */\nexport class JOSEError extends Error {\n  /**\n   * A unique error code for the particular error subclass.\n   *\n   * @ignore\n   */\n  static code = 'ERR_JOSE_GENERIC'\n\n  /** A unique error code for {@link JOSEError}. */\n  code = 'ERR_JOSE_GENERIC'\n\n  /** @ignore */\n  constructor(message?: string, options?: { cause?: unknown }) {\n    super(message, options)\n    this.name = this.constructor.name\n    // @ts-ignore\n    Error.captureStackTrace?.(this, this.constructor)\n  }\n}\n\n/**\n * An error subclass thrown when a JWT Claim Set member validation fails.\n *\n * @example\n *\n * Checking thrown error is this one using a stable error code\n *\n * ```js\n * if (err.code === 'ERR_JWT_CLAIM_VALIDATION_FAILED') {\n *   // ...\n * }\n * ```\n *\n * @example\n *\n * Checking thrown error is this one using `instanceof`\n *\n * ```js\n * if (err instanceof jose.errors.JWTClaimValidationFailed) {\n *   // ...\n * }\n * ```\n */\nexport class JWTClaimValidationFailed extends JOSEError {\n  /** @ignore */\n  static override code = 'ERR_JWT_CLAIM_VALIDATION_FAILED'\n\n  /** A unique error code for {@link JWTClaimValidationFailed}. */\n  override code = 'ERR_JWT_CLAIM_VALIDATION_FAILED'\n\n  /** The Claim for which the validation failed. */\n  claim: string\n\n  /** Reason code for the validation failure. */\n  reason: string\n\n  /**\n   * The parsed JWT Claims Set (aka payload). Other JWT claims may or may not have been verified at\n   * this point. The JSON Web Signature (JWS) or a JSON Web Encryption (JWE) structures' integrity\n   * has however been verified. Claims Set verification happens after the JWS Signature or JWE\n   * Decryption processes.\n   */\n  payload: types.JWTPayload\n\n  /** @ignore */\n  constructor(\n    message: string,\n    payload: types.JWTPayload,\n    claim = 'unspecified',\n    reason = 'unspecified',\n  ) {\n    super(message, { cause: { claim, reason, payload } })\n    this.claim = claim\n    this.reason = reason\n    this.payload = payload\n  }\n}\n\n/**\n * An error subclass thrown when a JWT is expired.\n *\n * @example\n *\n * Checking thrown error is this one using a stable error code\n *\n * ```js\n * if (err.code === 'ERR_JWT_EXPIRED') {\n *   // ...\n * }\n * ```\n *\n * @example\n *\n * Checking thrown error is this one using `instanceof`\n *\n * ```js\n * if (err instanceof jose.errors.JWTExpired) {\n *   // ...\n * }\n * ```\n */\nexport class JWTExpired extends JOSEError implements JWTClaimValidationFailed {\n  /** @ignore */\n  static override code = 'ERR_JWT_EXPIRED'\n\n  /** A unique error code for {@link JWTExpired}. */\n  override code = 'ERR_JWT_EXPIRED'\n\n  /** The Claim for which the validation failed. */\n  claim: string\n\n  /** Reason code for the validation failure. */\n  reason: string\n\n  /**\n   * The parsed JWT Claims Set (aka payload). Other JWT claims may or may not have been verified at\n   * this point. The JSON Web Signature (JWS) or a JSON Web Encryption (JWE) structures' integrity\n   * has however been verified. Claims Set verification happens after the JWS Signature or JWE\n   * Decryption processes.\n   */\n  payload: types.JWTPayload\n\n  /** @ignore */\n  constructor(\n    message: string,\n    payload: types.JWTPayload,\n    claim = 'unspecified',\n    reason = 'unspecified',\n  ) {\n    super(message, { cause: { claim, reason, payload } })\n    this.claim = claim\n    this.reason = reason\n    this.payload = payload\n  }\n}\n\n/**\n * An error subclass thrown when a JOSE Algorithm is not allowed per developer preference.\n *\n * @example\n *\n * Checking thrown error is this one using a stable error code\n *\n * ```js\n * if (err.code === 'ERR_JOSE_ALG_NOT_ALLOWED') {\n *   // ...\n * }\n * ```\n *\n * @example\n *\n * Checking thrown error is this one using `instanceof`\n *\n * ```js\n * if (err instanceof jose.errors.JOSEAlgNotAllowed) {\n *   // ...\n * }\n * ```\n */\nexport class JOSEAlgNotAllowed extends JOSEError {\n  /** @ignore */\n  static override code = 'ERR_JOSE_ALG_NOT_ALLOWED'\n\n  /** A unique error code for {@link JOSEAlgNotAllowed}. */\n  override code = 'ERR_JOSE_ALG_NOT_ALLOWED'\n}\n\n/**\n * An error subclass thrown when a particular feature or algorithm is not supported by this\n * implementation or JOSE in general.\n *\n * @example\n *\n * Checking thrown error is this one using a stable error code\n *\n * ```js\n * if (err.code === 'ERR_JOSE_NOT_SUPPORTED') {\n *   // ...\n * }\n * ```\n *\n * @example\n *\n * Checking thrown error is this one using `instanceof`\n *\n * ```js\n * if (err instanceof jose.errors.JOSENotSupported) {\n *   // ...\n * }\n * ```\n */\nexport class JOSENotSupported extends JOSEError {\n  /** @ignore */\n  static override code = 'ERR_JOSE_NOT_SUPPORTED'\n\n  /** A unique error code for {@link JOSENotSupported}. */\n  override code = 'ERR_JOSE_NOT_SUPPORTED'\n}\n\n/**\n * An error subclass thrown when a JWE ciphertext decryption fails.\n *\n * @example\n *\n * Checking thrown error is this one using a stable error code\n *\n * ```js\n * if (err.code === 'ERR_JWE_DECRYPTION_FAILED') {\n *   // ...\n * }\n * ```\n *\n * @example\n *\n * Checking thrown error is this one using `instanceof`\n *\n * ```js\n * if (err instanceof jose.errors.JWEDecryptionFailed) {\n *   // ...\n * }\n * ```\n */\nexport class JWEDecryptionFailed extends JOSEError {\n  /** @ignore */\n  static override code = 'ERR_JWE_DECRYPTION_FAILED'\n\n  /** A unique error code for {@link JWEDecryptionFailed}. */\n  override code = 'ERR_JWE_DECRYPTION_FAILED'\n\n  /** @ignore */\n  constructor(message = 'decryption operation failed', options?: { cause?: unknown }) {\n    super(message, options)\n  }\n}\n\n/**\n * An error subclass thrown when a JWE is invalid.\n *\n * @example\n *\n * Checking thrown error is this one using a stable error code\n *\n * ```js\n * if (err.code === 'ERR_JWE_INVALID') {\n *   // ...\n * }\n * ```\n *\n * @example\n *\n * Checking thrown error is this one using `instanceof`\n *\n * ```js\n * if (err instanceof jose.errors.JWEInvalid) {\n *   // ...\n * }\n * ```\n */\nexport class JWEInvalid extends JOSEError {\n  /** @ignore */\n  static override code = 'ERR_JWE_INVALID'\n\n  /** A unique error code for {@link JWEInvalid}. */\n  override code = 'ERR_JWE_INVALID'\n}\n\n/**\n * An error subclass thrown when a JWS is invalid.\n *\n * @example\n *\n * Checking thrown error is this one using a stable error code\n *\n * ```js\n * if (err.code === 'ERR_JWS_INVALID') {\n *   // ...\n * }\n * ```\n *\n * @example\n *\n * Checking thrown error is this one using `instanceof`\n *\n * ```js\n * if (err instanceof jose.errors.JWSInvalid) {\n *   // ...\n * }\n * ```\n */\nexport class JWSInvalid extends JOSEError {\n  /** @ignore */\n  static override code = 'ERR_JWS_INVALID'\n\n  /** A unique error code for {@link JWSInvalid}. */\n  override code = 'ERR_JWS_INVALID'\n}\n\n/**\n * An error subclass thrown when a JWT is invalid.\n *\n * @example\n *\n * Checking thrown error is this one using a stable error code\n *\n * ```js\n * if (err.code === 'ERR_JWT_INVALID') {\n *   // ...\n * }\n * ```\n *\n * @example\n *\n * Checking thrown error is this one using `instanceof`\n *\n * ```js\n * if (err instanceof jose.errors.JWTInvalid) {\n *   // ...\n * }\n * ```\n */\nexport class JWTInvalid extends JOSEError {\n  /** @ignore */\n  static override code = 'ERR_JWT_INVALID'\n\n  /** A unique error code for {@link JWTInvalid}. */\n  override code = 'ERR_JWT_INVALID'\n}\n\n/**\n * An error subclass thrown when a JWK is invalid.\n *\n * @example\n *\n * Checking thrown error is this one using a stable error code\n *\n * ```js\n * if (err.code === 'ERR_JWK_INVALID') {\n *   // ...\n * }\n * ```\n *\n * @example\n *\n * Checking thrown error is this one using `instanceof`\n *\n * ```js\n * if (err instanceof jose.errors.JWKInvalid) {\n *   // ...\n * }\n * ```\n */\nexport class JWKInvalid extends JOSEError {\n  /** @ignore */\n  static override code = 'ERR_JWK_INVALID'\n\n  /** A unique error code for {@link JWKInvalid}. */\n  override code = 'ERR_JWK_INVALID'\n}\n\n/**\n * An error subclass thrown when a JWKS is invalid.\n *\n * @example\n *\n * Checking thrown error is this one using a stable error code\n *\n * ```js\n * if (err.code === 'ERR_JWKS_INVALID') {\n *   // ...\n * }\n * ```\n *\n * @example\n *\n * Checking thrown error is this one using `instanceof`\n *\n * ```js\n * if (err instanceof jose.errors.JWKSInvalid) {\n *   // ...\n * }\n * ```\n */\nexport class JWKSInvalid extends JOSEError {\n  /** @ignore */\n  static override code = 'ERR_JWKS_INVALID'\n\n  /** A unique error code for {@link JWKSInvalid}. */\n  override code = 'ERR_JWKS_INVALID'\n}\n\n/**\n * An error subclass thrown when no keys match from a JWKS.\n *\n * @example\n *\n * Checking thrown error is this one using a stable error code\n *\n * ```js\n * if (err.code === 'ERR_JWKS_NO_MATCHING_KEY') {\n *   // ...\n * }\n * ```\n *\n * @example\n *\n * Checking thrown error is this one using `instanceof`\n *\n * ```js\n * if (err instanceof jose.errors.JWKSNoMatchingKey) {\n *   // ...\n * }\n * ```\n */\nexport class JWKSNoMatchingKey extends JOSEError {\n  /** @ignore */\n  static override code = 'ERR_JWKS_NO_MATCHING_KEY'\n\n  /** A unique error code for {@link JWKSNoMatchingKey}. */\n  override code = 'ERR_JWKS_NO_MATCHING_KEY'\n\n  /** @ignore */\n  constructor(\n    message = 'no applicable key found in the JSON Web Key Set',\n    options?: { cause?: unknown },\n  ) {\n    super(message, options)\n  }\n}\n\n/**\n * An error subclass thrown when multiple keys match from a JWKS.\n *\n * @example\n *\n * Checking thrown error is this one using a stable error code\n *\n * ```js\n * if (err.code === 'ERR_JWKS_MULTIPLE_MATCHING_KEYS') {\n *   // ...\n * }\n * ```\n *\n * @example\n *\n * Checking thrown error is this one using `instanceof`\n *\n * ```js\n * if (err instanceof jose.errors.JWKSMultipleMatchingKeys) {\n *   // ...\n * }\n * ```\n */\nexport class JWKSMultipleMatchingKeys extends JOSEError {\n  /** @ignore */\n  [Symbol.asyncIterator]!: () => AsyncIterableIterator<types.CryptoKey>\n\n  /** @ignore */\n  static override code = 'ERR_JWKS_MULTIPLE_MATCHING_KEYS'\n\n  /** A unique error code for {@link JWKSMultipleMatchingKeys}. */\n  override code = 'ERR_JWKS_MULTIPLE_MATCHING_KEYS'\n\n  /** @ignore */\n  constructor(\n    message = 'multiple matching keys found in the JSON Web Key Set',\n    options?: { cause?: unknown },\n  ) {\n    super(message, options)\n  }\n}\n\n/**\n * Timeout was reached when retrieving the JWKS response.\n *\n * @example\n *\n * Checking thrown error is this one using a stable error code\n *\n * ```js\n * if (err.code === 'ERR_JWKS_TIMEOUT') {\n *   // ...\n * }\n * ```\n *\n * @example\n *\n * Checking thrown error is this one using `instanceof`\n *\n * ```js\n * if (err instanceof jose.errors.JWKSTimeout) {\n *   // ...\n * }\n * ```\n */\nexport class JWKSTimeout extends JOSEError {\n  /** @ignore */\n  static override code = 'ERR_JWKS_TIMEOUT'\n\n  /** A unique error code for {@link JWKSTimeout}. */\n  override code = 'ERR_JWKS_TIMEOUT'\n\n  /** @ignore */\n  constructor(message = 'request timed out', options?: { cause?: unknown }) {\n    super(message, options)\n  }\n}\n\n/**\n * An error subclass thrown when JWS signature verification fails.\n *\n * @example\n *\n * Checking thrown error is this one using a stable error code\n *\n * ```js\n * if (err.code === 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') {\n *   // ...\n * }\n * ```\n *\n * @example\n *\n * Checking thrown error is this one using `instanceof`\n *\n * ```js\n * if (err instanceof jose.errors.JWSSignatureVerificationFailed) {\n *   // ...\n * }\n * ```\n */\nexport class JWSSignatureVerificationFailed extends JOSEError {\n  /** @ignore */\n  static override code = 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED'\n\n  /** A unique error code for {@link JWSSignatureVerificationFailed}. */\n  override code = 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED'\n\n  /** @ignore */\n  constructor(message = 'signature verification failed', options?: { cause?: unknown }) {\n    super(message, options)\n  }\n}\n"
  },
  {
    "path": "tap/.browser.ts",
    "content": "import { test, expect } from '@playwright/test'\nimport { createServer } from 'node:http'\nimport { readFileSync } from 'node:fs'\n\nconst script = readFileSync('./tap/run-browser.js', 'utf-8')\n\ntest('passes tests', async ({ page }) => {\n  const server = createServer((req, res) => {\n    if (req.url === '/run-browser.js') {\n      res.writeHead(200, { 'Content-Type': 'application/javascript' })\n      res.end(script)\n    } else {\n      res.writeHead(200, { 'Content-Type': 'text/html' })\n      res.end(\n        '<!DOCTYPE html><html><head></head><body><script type=\"module\" src=\"/run-browser.js\"></script></body></html>',\n      )\n    }\n  })\n\n  await new Promise<void>((resolve) => server.listen(0, resolve))\n  const port = (server.address() as import('node:net').AddressInfo).port\n\n  page.on('console', (msg) => {\n    if (msg.type() === 'log') {\n      console.log(msg.text())\n    }\n  })\n\n  await page.goto(`http://localhost:${port}`)\n\n  let stats\n  do {\n    await page.waitForTimeout(1000)\n    stats = await page.evaluate(() => (globalThis as any).stats)\n  } while (!stats)\n\n  server.close()\n  expect(stats.failed).toBe(0)\n})\n"
  },
  {
    "path": "tap/.browsers.sh",
    "content": "#!/bin/bash\n./node_modules/.bin/esbuild \\\n  --log-level=warning \\\n  --format=esm \\\n  --bundle \\\n  --minify \\\n  --target=esnext \\\n  --outfile=tap/run-browser.js \\\n  tap/run-browser.ts\n\n: \"${BROWSER:=chromium}\"\n\nnpx playwright test --project=\"$BROWSER\"\n"
  },
  {
    "path": "tap/.bun.sh",
    "content": "echo \"Using Bun `bun -v`\"\n\nbun run tap/run-bun.ts\n"
  },
  {
    "path": "tap/.deno.sh",
    "content": "#!/bin/bash\n\necho \"Using $(deno --version | head -1)\"\n\ndeno run --allow-read --allow-net --allow-env --unstable-sloppy-imports tap/run-deno.ts\n"
  },
  {
    "path": "tap/.electron.sh",
    "content": "#!/bin/bash\n\nsource .electron_flags.sh\nelectron tap/run-electron.ts\n"
  },
  {
    "path": "tap/.node.sh",
    "content": "#!/bin/bash\n\nsource .node_flags.sh\n\nnode tap/run-node.ts\nWEB_CRYPTO_API=$?\n\nnode tap/run-node.ts --keys='KeyObject'\nWEB_CRYPTO_API_WITH_KEYOBJECT=$?\n\necho \"\"\necho \"Node.js with CryptoKey inputs\"\ntest $WEB_CRYPTO_API -eq 0 && echo \"  passed\" || echo \"  failed\"\n\necho \"\"\necho \"Node.js with KeyObject inputs\"\ntest $WEB_CRYPTO_API_WITH_KEYOBJECT -eq 0 && echo \"  passed\" || echo \"  failed\"\n\ntest $WEB_CRYPTO_API -eq 0 && test $WEB_CRYPTO_API_WITH_KEYOBJECT -eq 0\n"
  },
  {
    "path": "tap/.workerd.sh",
    "content": "#!/bin/bash\n\nCOMPATIBILITY_DATE=$(node -p \"const d = require('workerd').compatibilityDate, t = new Date().toISOString().slice(0,10); d > t ? t : d\")\nWORKERD_VERSION=$(npm ls --global --json | jq -r '.dependencies.workerd.version')\n\necho \"Using workerd $WORKERD_VERSION, compatibility date $COMPATIBILITY_DATE\"\n\n./node_modules/.bin/esbuild \\\n  --log-level=warning \\\n  --format=esm \\\n  --bundle \\\n  --define:WORKERD_VERSION=\\\"$WORKERD_VERSION\\\" \\\n  --target=esnext \\\n  --outfile=tap/run-workerd.js \\\n  tap/run-workerd.ts\n\ngenerate_capnp() {\n  local compatibility_flags=$1\n  cat <<EOT > $(pwd)/tap/.workerd.capnp\nusing Workerd = import \"/workerd/workerd.capnp\";\n\nconst config :Workerd.Config = (\n  services = [\n    (name = \"main\", worker = .tapWorker),\n  ],\n);\n\nconst tapWorker :Workerd.Worker = (\n  modules = [\n    (name = \"worker\", esModule = embed \"run-workerd.js\")\n  ],\n  compatibilityDate = \"$COMPATIBILITY_DATE\",\n  compatibilityFlags = $compatibility_flags\n);\nEOT\n}\n\nrun_test() {\n  local compatibility_flags=$1\n  generate_capnp \"$compatibility_flags\"\n  workerd test --verbose $(pwd)/tap/.workerd.capnp\n  return $?\n}\n\nrun_test \"[]\"\nNO_COMPAT=$?\n\nrun_test '[\"nodejs_compat\"]'\nCOMPAT=$?\n\necho \"\"\necho \"Workerd without nodejs_compat\"\ntest $NO_COMPAT -eq 0 && echo \"  passed\" || echo \"  failed\"\n\necho \"\"\necho \"Workerd with nodejs_compat\"\ntest $COMPAT -eq 0 && echo \"  passed\" || echo \"  failed\"\n\ntest $NO_COMPAT -eq 0 && test $COMPAT -eq 0\n"
  },
  {
    "path": "tap/aes.ts",
    "content": "import type QUnit from 'qunit'\nimport * as env from './env.js'\nimport type * as jose from '../src/index.js'\nimport * as roundtrip from './encrypt.js'\n\nexport default (\n  QUnit: QUnit,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n) => {\n  const { module, test } = QUnit\n  module('aes.ts')\n\n  const algorithms = [\n    'A128GCM',\n    'A192GCM',\n    'A256GCM',\n    'A128CBC-HS256',\n    'A192CBC-HS384',\n    'A256CBC-HS512',\n  ]\n\n  function title(algorithm: string, supported = true) {\n    let result = ''\n    if (!supported) {\n      result = '[not supported] '\n    }\n    result += `${algorithm}`\n    return result\n  }\n\n  function secretsFor(enc: string) {\n    return [\n      keys.generateSecret(enc, { extractable: true }),\n      crypto.getRandomValues(\n        new Uint8Array(parseInt(enc.endsWith('GCM') ? enc.slice(1, 4) : enc.slice(-3)) >> 3),\n      ),\n    ]\n  }\n\n  for (const enc of algorithms) {\n    const execute = async (t: typeof QUnit.assert) => {\n      for await (const secret of secretsFor(enc)) {\n        await roundtrip.jwe(t, lib, keys, 'dir', enc, secret)\n      }\n    }\n\n    const jwt = async (t: typeof QUnit.assert) => {\n      await roundtrip.jwt(t, lib, keys, 'dir', enc, await secretsFor(enc)[0])\n    }\n\n    if (env.supported(enc)) {\n      test(title(enc), execute)\n      test(`${title(enc)} JWT`, jwt)\n    } else {\n      test(title(enc, false), async (t) => {\n        await t.rejects(execute(t))\n      })\n    }\n  }\n}\n"
  },
  {
    "path": "tap/aeskw.ts",
    "content": "import type QUnit from 'qunit'\nimport * as env from './env.js'\nimport type * as jose from '../src/index.js'\nimport * as roundtrip from './encrypt.js'\n\nexport default (\n  QUnit: QUnit,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n) => {\n  const { module, test } = QUnit\n  module('aeskw.ts')\n\n  const algorithms = ['A128KW', 'A192KW', 'A256KW', 'A128GCMKW', 'A192GCMKW', 'A256GCMKW']\n\n  function title(algorithm: string, supported = true) {\n    let result = ''\n    if (!supported) {\n      result = '[not supported] '\n    }\n    result += `${algorithm}`\n    return result\n  }\n\n  function secretsFor(alg: string) {\n    return [\n      keys.generateSecret(alg, { extractable: true }),\n      crypto.getRandomValues(new Uint8Array(parseInt(alg.slice(1, 4), 10) >> 3)),\n    ]\n  }\n\n  for (const alg of algorithms) {\n    const execute = async (t: typeof QUnit.assert) => {\n      for await (const secret of secretsFor(alg)) {\n        await roundtrip.jwe(t, lib, keys, alg, 'A128GCM', secret)\n      }\n    }\n\n    const jwt = async (t: typeof QUnit.assert) => {\n      await roundtrip.jwt(t, lib, keys, alg, 'A128GCM', await secretsFor(alg)[0])\n    }\n\n    if (env.supported(alg)) {\n      test(title(alg), execute)\n      test(`${title(alg)} JWT`, jwt)\n    } else {\n      test(title(alg, false), async (t) => {\n        await t.rejects(execute(t))\n      })\n    }\n  }\n}\n"
  },
  {
    "path": "tap/cookbook.ts",
    "content": "import type QUnit from 'qunit'\nimport * as env from './env.js'\nimport type * as jose from '../src/index.js'\n\n// @ts-ignore\nimport jwsVectors from '../cookbook/jws.mjs'\n// @ts-ignore\nimport jweVectors from '../cookbook/jwe.mjs'\n\nexport default (\n  QUnit: QUnit,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n) => {\n  const { module, test } = QUnit\n\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n\n  const pubjwk = (jwk: jose.JWK) => {\n    const { d, p, q, dp, dq, qi, priv, ...publicJwk } = jwk\n    return publicJwk\n  }\n\n  {\n    module('jws cookbook')\n\n    const flattened = {\n      Sign: lib.FlattenedSign,\n      verify: lib.flattenedVerify,\n    }\n    const compact = {\n      Sign: lib.CompactSign,\n      verify: lib.compactVerify,\n    }\n\n    function supported(vector: any) {\n      return env.supported(vector.input.alg)\n    }\n\n    const execute = (vector: any) => async (t: typeof QUnit.assert) => {\n      const privateKey = await keys.importJWK(vector.input.key, vector.input.alg)\n      const publicKey = await keys.importJWK(pubjwk(vector.input.key), vector.input.alg)\n\n      if (vector.deterministic) {\n        // sign and compare results are the same\n        const runs = [[flattened, vector.output.json_flat]]\n        if (vector.signing.protected?.b64 !== undefined) {\n          runs.push([compact, vector.output.compact])\n        }\n        for (const [serialization, expectedResult] of runs) {\n          if (!expectedResult) {\n            continue\n          }\n          const sign = new serialization.Sign(encode(vector.input.payload))\n\n          if (vector.signing.protected) {\n            sign.setProtectedHeader(vector.signing.protected)\n          }\n\n          if (vector.signing.unprotected) {\n            sign.setUnprotectedHeader(vector.signing.unprotected)\n          }\n\n          const result = await sign.sign(privateKey)\n\n          if (vector.signing.protected?.b64 === false) {\n            await serialization.verify(\n              { ...result, payload: encode(vector.input.payload) },\n              publicKey,\n            )\n          } else {\n            await serialization.verify(result, publicKey)\n          }\n\n          if (typeof result === 'object') {\n            Object.entries(expectedResult).forEach(([prop, expected]) => {\n              if (prop === 'payload' && vector.signing.protected?.b64 === false) {\n                return\n              }\n              t.equal(JSON.stringify(result[prop]), JSON.stringify(expected))\n            })\n          } else {\n            t.equal(result, expectedResult)\n          }\n        }\n      } else {\n        const sign = new flattened.Sign(encode(vector.input.payload))\n\n        if (vector.signing.protected) {\n          sign.setProtectedHeader(vector.signing.protected)\n        }\n\n        if (vector.signing.unprotected) {\n          sign.setUnprotectedHeader(vector.signing.unprotected)\n        }\n\n        const result = await sign.sign(privateKey)\n        await flattened.verify(result, publicKey)\n      }\n\n      if (vector.output.json_flat) {\n        await flattened.verify(vector.output.json_flat, publicKey)\n      }\n      if (vector.output.compact) {\n        await compact.verify(vector.output.compact, publicKey)\n      }\n\n      t.ok(1)\n    }\n\n    for (const vector of jwsVectors) {\n      if (supported(vector)) {\n        test(vector.title, execute(vector))\n      } else {\n        test(`[not supported] ${vector.title}`, async (t) => {\n          await t.rejects(execute(vector)(t))\n        })\n      }\n    }\n  }\n\n  {\n    module('jwe cookbook')\n\n    const flattened = {\n      Encrypt: lib.FlattenedEncrypt,\n      decrypt: lib.flattenedDecrypt,\n    }\n    const compact = {\n      Encrypt: lib.CompactEncrypt,\n      decrypt: lib.compactDecrypt,\n    }\n\n    function supported(vector: any) {\n      if (vector.input.zip && typeof globalThis.CompressionStream === 'undefined') {\n        return false\n      }\n      return env.supported(vector.input.alg) && env.supported(vector.input.enc)\n    }\n\n    const toJWK = (input: string | jose.JWK) => {\n      if (typeof input === 'string') {\n        return {\n          kty: 'oct',\n          k: lib.base64url.encode(encode(input)),\n        }\n      }\n      return input\n    }\n\n    const execute = (vector: any) => async (t: typeof QUnit.assert) => {\n      const dir = vector.input.alg === 'dir'\n\n      if (vector.deterministic) {\n        // encrypt and compare results are the same\n        for (const [serialization, expectedResult] of [\n          [flattened, vector.output.json_flat],\n          [compact, vector.output.compact],\n        ]) {\n          if (!expectedResult) {\n            continue\n          }\n          const encrypt = new serialization.Encrypt(encode(vector.input.plaintext))\n\n          if (vector.encrypting_content.protected) {\n            encrypt.setProtectedHeader(vector.encrypting_content.protected)\n          }\n\n          if (vector.encrypting_content.unprotected) {\n            encrypt.setSharedUnprotectedHeader(vector.encrypting_content.unprotected)\n          }\n\n          const { cek, iv } = vector.generated\n\n          if (cek) {\n            encrypt.setContentEncryptionKey(lib.base64url.decode(cek))\n          }\n\n          if (iv) {\n            encrypt.setInitializationVector(lib.base64url.decode(iv))\n          }\n\n          if (vector.input.aad) {\n            encrypt.setAdditionalAuthenticatedData(encode(vector.input.aad))\n          }\n\n          const keyManagementParameters: jose.JWEKeyManagementHeaderParameters = {}\n\n          if (vector.encrypting_key && vector.encrypting_key.iv) {\n            keyManagementParameters.iv = lib.base64url.decode(vector.encrypting_key.iv)\n          }\n\n          if (vector.encrypting_key && vector.encrypting_key.iteration_count) {\n            keyManagementParameters.p2c = vector.encrypting_key.iteration_count\n          }\n\n          if (vector.encrypting_key && vector.encrypting_key.salt) {\n            keyManagementParameters.p2s = lib.base64url.decode(vector.encrypting_key.salt)\n          }\n\n          if (vector.encrypting_key && vector.encrypting_key.epk) {\n            keyManagementParameters.epk = (await keys.importJWK(\n              vector.encrypting_key.epk,\n              vector.input.alg,\n            )) as jose.KeyLike\n          }\n\n          if (Object.keys(keyManagementParameters).length !== 0) {\n            encrypt.setKeyManagementParameters(keyManagementParameters)\n          }\n\n          const publicKey = await keys.importJWK(\n            pubjwk(toJWK(vector.input.pwd || vector.input.key)),\n            dir ? vector.input.enc : vector.input.alg,\n          )\n\n          const result = await encrypt.encrypt(publicKey)\n\n          if (typeof result === 'object') {\n            Object.entries(expectedResult).forEach(([prop, expected]) => {\n              t.equal(JSON.stringify(result[prop]), JSON.stringify(expected))\n            })\n          } else {\n            t.equal(result, expectedResult)\n          }\n        }\n      } else {\n        const encrypt = new flattened.Encrypt(encode(vector.input.plaintext))\n\n        if (vector.encrypting_content.protected) {\n          encrypt.setProtectedHeader(vector.encrypting_content.protected)\n        }\n\n        if (vector.encrypting_content.unprotected) {\n          encrypt.setUnprotectedHeader(vector.encrypting_content.unprotected)\n        }\n\n        const privateKey = (await keys.importJWK(\n          toJWK(vector.input.pwd || vector.input.key),\n          dir ? vector.input.enc : vector.input.alg,\n        )) as jose.KeyLike\n        let publicKey\n        if (privateKey.type === 'secret') {\n          publicKey = privateKey\n        } else {\n          publicKey = await keys.importJWK(\n            pubjwk(toJWK(vector.input.pwd || vector.input.key)),\n            dir ? vector.input.enc : vector.input.alg,\n          )\n        }\n\n        const result = await encrypt.encrypt(publicKey)\n        await flattened.decrypt(result, privateKey, {\n          keyManagementAlgorithms: [vector.input.alg],\n          contentEncryptionAlgorithms: [vector.input.enc],\n        })\n      }\n\n      const privateKey = await keys.importJWK(\n        toJWK(vector.input.pwd || vector.input.key),\n        dir ? vector.input.enc : vector.input.alg,\n      )\n      if (vector.output.json_flat) {\n        await flattened.decrypt(vector.output.json_flat, privateKey, {\n          keyManagementAlgorithms: [vector.input.alg],\n          contentEncryptionAlgorithms: [vector.input.enc],\n        })\n      }\n      if (vector.output.compact) {\n        await compact.decrypt(vector.output.compact, privateKey, {\n          keyManagementAlgorithms: [vector.input.alg],\n          contentEncryptionAlgorithms: [vector.input.enc],\n        })\n      }\n      t.ok(1)\n    }\n\n    for (const vector of jweVectors) {\n      if (supported(vector)) {\n        test(vector.title, execute(vector))\n      } else {\n        test(`[not supported] ${vector.title}`, async (t) => {\n          await t.rejects(execute(vector)(t))\n        })\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "tap/ecdh.ts",
    "content": "import type QUnit from 'qunit'\nimport * as env from './env.js'\nimport type * as jose from '../src/index.js'\nimport * as roundtrip from './encrypt.js'\n\nexport default (\n  QUnit: QUnit,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n) => {\n  const { module, test } = QUnit\n  module('ecdh.ts')\n\n  const kps: Record<string, jose.GenerateKeyPairResult> = {}\n\n  type Vector = [string, jose.GenerateKeyPairOptions]\n  const algorithms: Vector[] = [\n    ['ECDH-ES', { crv: 'P-256' }],\n    ['ECDH-ES', { crv: 'P-384' }],\n    ['ECDH-ES', { crv: 'P-521' }],\n    ['ECDH-ES', { crv: 'X25519' }],\n  ]\n\n  function curve(options?: jose.GenerateKeyPairOptions) {\n    return options?.crv || 'P-256'\n  }\n\n  function title(vector: Vector, supported = true) {\n    const [alg, options] = vector\n    let result = ''\n    const crv = curve(options)\n    if (!supported) {\n      result = '[not supported] '\n    }\n    result += `${alg} ${crv}`\n    return result\n  }\n\n  for (const vector of algorithms) {\n    const [alg, options] = vector\n    const k = options?.crv || alg\n\n    const execute = async (t: typeof QUnit.assert) => {\n      if (!kps[k]) {\n        kps[k] = await keys.generateKeyPair(alg, { ...options, extractable: true })\n      }\n      await roundtrip.jwe(t, lib, keys, alg, 'A128GCM', kps[k])\n    }\n\n    const jwt = async (t: typeof QUnit.assert) => {\n      if (!kps[k]) {\n        kps[k] = await keys.generateKeyPair(alg, { ...options, extractable: true })\n      }\n      await roundtrip.jwt(t, lib, keys, alg, 'A128GCM', kps[k])\n    }\n\n    if (env.supported(alg) && env.supported(curve(options))) {\n      test(title(vector), execute)\n      test(`${title(vector)} JWT`, jwt)\n    } else {\n      test(title(vector, false), async (t) => {\n        await t.rejects(execute(t))\n      })\n    }\n  }\n}\n"
  },
  {
    "path": "tap/encrypt.ts",
    "content": "import type QUnit from 'qunit'\nimport type * as jose from '../src/index.js'\n\ntype keyType = Uint8Array | jose.CryptoKey | jose.KeyObject | jose.GenerateKeyPairResult\n\nfunction isKeyPair(input: keyType): input is jose.GenerateKeyPairResult {\n  return 'publicKey' in input && 'privateKey' in input\n}\n\nasync function getKeys(\n  secretOrKeyPair: keyType,\n  jwk: false,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n): Promise<Array<Uint8Array | jose.CryptoKey | jose.KeyObject>>\nasync function getKeys(\n  secretOrKeyPair: keyType,\n  jwk: true,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n): Promise<Array<jose.JWK>>\nasync function getKeys(\n  secretOrKeyPair: keyType,\n  jwk: boolean,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n) {\n  let dKey = isKeyPair(secretOrKeyPair) ? secretOrKeyPair.privateKey : secretOrKeyPair\n  let eKey = isKeyPair(secretOrKeyPair) ? secretOrKeyPair.publicKey : secretOrKeyPair\n\n  if (jwk) {\n    // @ts-ignore\n    return [await keys.exportJWK(eKey), await keys.exportJWK(dKey)]\n  }\n\n  return [eKey, dKey]\n}\n\nfunction jwkWithProps(jwk: jose.JWK, alg: string, enc: string) {\n  jwk = structuredClone(jwk)\n  jwk.alg = alg === 'dir' ? enc : alg\n  jwk.use = 'enc'\n  if (jwk.k) {\n    if (jwk.alg.match(/^A\\d{3}KW$/)) {\n      jwk.key_ops = ['wrapKey', 'unwrapKey']\n    } else {\n      jwk.key_ops = ['encrypt', 'decrypt']\n    }\n  } else if (jwk.kty === 'RSA') {\n    if (jwk.d) {\n      jwk.key_ops = ['unwrapKey', 'decrypt']\n    } else {\n      jwk.key_ops = ['wrapKey', 'encrypt']\n    }\n  } else if (jwk.kty === 'EC') {\n    if (jwk.d) {\n      jwk.key_ops = ['deriveBits']\n    } else {\n      jwk.key_ops = []\n    }\n  } else if (jwk.kty === 'OKP') {\n    if (jwk.d) {\n      jwk.key_ops = ['deriveBits']\n    } else {\n      jwk.key_ops = []\n    }\n  }\n\n  return jwk\n}\n\nexport async function jwe(\n  t: typeof QUnit.assert,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n  alg: string,\n  enc: string,\n  secretOrKeyPair: keyType,\n  cleartext = crypto.getRandomValues(new Uint8Array(16)),\n) {\n  // Test Uint8Array, CryptoKey, and KeyObject key inputs\n  {\n    const [eKey, dKey] = await getKeys(secretOrKeyPair, false, keys)\n    const aad = crypto.getRandomValues(new Uint8Array(16))\n\n    const jwe = await new lib.FlattenedEncrypt(cleartext)\n      .setProtectedHeader({ alg, enc })\n      .setAdditionalAuthenticatedData(aad)\n      .encrypt(eKey)\n\n    for (const key of [dKey, async () => dKey]) {\n      // @ts-ignore\n      const decrypted = await lib.flattenedDecrypt(jwe, key, {\n        keyManagementAlgorithms: [alg],\n        contentEncryptionAlgorithms: [enc],\n      })\n      t.deepEqual([...decrypted.plaintext], [...cleartext])\n      t.deepEqual([...decrypted.additionalAuthenticatedData!], [...aad])\n    }\n  }\n\n  if (secretOrKeyPair instanceof Uint8Array) return\n\n  // Test JWK key input\n  {\n    const [eKey, dKey] = await getKeys(secretOrKeyPair, true, keys)\n    const aad = crypto.getRandomValues(new Uint8Array(16))\n\n    const jwe = await new lib.FlattenedEncrypt(cleartext)\n      .setProtectedHeader({ alg, enc })\n      .setAdditionalAuthenticatedData(aad)\n      .encrypt(eKey)\n\n    {\n      await new lib.FlattenedEncrypt(cleartext)\n        .setProtectedHeader({ alg, enc })\n        .setAdditionalAuthenticatedData(aad)\n        .encrypt(jwkWithProps(eKey, alg, enc))\n    }\n\n    for (const key of [\n      dKey,\n      async () => dKey,\n      jwkWithProps(dKey, alg, enc),\n      async () => jwkWithProps(dKey, alg, enc),\n    ]) {\n      // @ts-ignore\n      const decrypted = await lib.flattenedDecrypt(jwe, key, {\n        keyManagementAlgorithms: [alg],\n        contentEncryptionAlgorithms: [enc],\n      })\n      t.deepEqual([...decrypted.plaintext], [...cleartext])\n      t.deepEqual([...decrypted.additionalAuthenticatedData!], [...aad])\n    }\n  }\n}\n\nexport async function jwt(\n  t: typeof QUnit.assert,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n  alg: string,\n  enc: string,\n  secretOrKeyPair: Uint8Array | jose.KeyLike | jose.GenerateKeyPairResult,\n) {\n  const [eKey, dKey] = await getKeys(secretOrKeyPair, false, keys)\n\n  const jwt = await new lib.EncryptJWT({ foo: 'bar', '🤷‍♂️': '🤷‍♀️' })\n    .setProtectedHeader({ alg, enc, '🤷‍♂️': '🤷‍♀️' })\n    .encrypt(eKey)\n\n  for (const key of [dKey, async () => dKey]) {\n    // @ts-ignore\n    const decrypted = await lib.jwtDecrypt(jwt, key, {\n      keyManagementAlgorithms: [alg],\n      contentEncryptionAlgorithms: [enc],\n    })\n    if (enc) {\n      t.propContains(decrypted, {\n        payload: {\n          foo: 'bar',\n          '🤷‍♂️': '🤷‍♀️',\n        },\n        protectedHeader: {\n          alg,\n          enc,\n          '🤷‍♂️': '🤷‍♀️',\n        },\n      })\n    } else {\n      t.propContains(decrypted, {\n        payload: {\n          foo: 'bar',\n        },\n        protectedHeader: {\n          alg,\n          '🤷‍♂️': '🤷‍♀️',\n        },\n      })\n    }\n  }\n}\n"
  },
  {
    "path": "tap/env.ts",
    "content": "// @ts-ignore\nexport const isBun = typeof Bun !== 'undefined'\n\n// @ts-ignore\nexport const isElectron = typeof process !== 'undefined' && process.versions?.electron !== undefined\n\n// @ts-ignore\nexport const isDeno = typeof Deno !== 'undefined'\n\nexport const isBrowser =\n  typeof navigator !== 'undefined' && navigator.userAgent?.startsWith?.('Mozilla/5.0 ')\n\nexport const isWorkerd =\n  typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers'\n\n// @ts-ignore\nexport const isNode =\n  !isBun && !isElectron && !isDeno && !isWorkerd && typeof process !== 'undefined'\n\nconst BOWSER = 'https://cdn.jsdelivr.net/npm/bowser@2.11.0/src/bowser.js'\n\nlet parsedUserAgent: any\nasync function parseUserAgent() {\n  const { default: Bowser } = await import(BOWSER)\n  parsedUserAgent || (parsedUserAgent = Bowser.parse(window.navigator.userAgent))\n  return parsedUserAgent\n}\n\nasync function isEngine(engine: string) {\n  const userAgentData = await parseUserAgent()\n  return userAgentData.engine.name === engine\n}\n\nexport function isBrowserVersionAtLeast(version: number) {\n  if (!parsedUserAgent) throw new Error()\n  return parseInt(parsedUserAgent.browser.version.split('.')[0], 10) >= version\n}\n\nexport const isBlink = isBrowser && (await isEngine('Blink'))\n\nexport const isWebKit = isBrowser && (await isEngine('WebKit'))\n\nexport const isGecko = isBrowser && (await isEngine('Gecko'))\n\nfunction isNodeVersionAtLeast(major: number, minor: number) {\n  const parts = process.versions.node.split('.').map((i) => parseInt(i, 10))\n  return parts[0] > major || (parts[0] === major && parts[1] >= minor)\n}\n\nexport function supported(identifier?: string, op?: string) {\n  switch (identifier) {\n    case 'RSA1_5':\n    case 'X448':\n    case 'Ed448':\n    case 'ES256K':\n    case 'secp256k1':\n      return false\n  }\n\n  switch (identifier) {\n    case 'ML-DSA-44':\n    case 'ML-DSA-65':\n    case 'ML-DSA-87':\n      return isNode && isNodeVersionAtLeast(24, 7)\n  }\n\n  if (isBlink) {\n    switch (identifier) {\n      case 'A192CBC-HS384':\n      case 'A192GCM':\n      case 'A192GCMKW':\n      case 'A192KW':\n      case 'PBES2-HS384+A192KW':\n        return false\n    }\n  }\n\n  if (isElectron) {\n    switch (identifier) {\n      case 'A128KW':\n      case 'A192KW':\n      case 'A256KW':\n      case 'PBES2-HS256+A128KW':\n      case 'PBES2-HS384+A192KW':\n      case 'PBES2-HS512+A256KW':\n      case 'ECDH-ES+A128KW':\n      case 'ECDH-ES+A192KW':\n      case 'ECDH-ES+A256KW':\n        return false\n    }\n  }\n\n  if (isBun && identifier === 'X25519') {\n    switch (op) {\n      case 'private jwk import':\n      case 'public jwk import':\n      case 'pem import':\n        return true\n      default:\n        return false\n    }\n  }\n\n  if (isDeno) {\n    if (\n      (identifier === 'P-521' || identifier === 'ES512') &&\n      op !== 'pem import' &&\n      op !== 'public jwk import' &&\n      op !== 'private jwk import'\n    ) {\n      return false\n    }\n  }\n\n  return true\n}\n"
  },
  {
    "path": "tap/fixtures.ts",
    "content": "export const KEYS = {\n  Ed25519: {\n    jwk: {\n      crv: 'Ed25519',\n      d: 'lootR5J6UdF-1tvFpnCZzr2N9AmRwgX92MzH_uuaGCQ',\n      kty: 'OKP',\n      x: 'lBZ9GShvbQEtyyaGs-0Nd4aurH7ERq6UOIvXGb5_tXA',\n    },\n    pkcs8:\n      '-----BEGIN PRIVATE KEY-----\\n' +\n      'MC4CAQAwBQYDK2VwBCIEIJaKLUeSelHRftbbxaZwmc69jfQJkcIF/djMx/7rmhgk\\n' +\n      '-----END PRIVATE KEY-----\\n',\n    spki:\n      '-----BEGIN PUBLIC KEY-----\\n' +\n      'MCowBQYDK2VwAyEAlBZ9GShvbQEtyyaGs+0Nd4aurH7ERq6UOIvXGb5/tXA=\\n' +\n      '-----END PUBLIC KEY-----\\n',\n    x509:\n      '-----BEGIN CERTIFICATE-----\\n' +\n      'MIIBoTCCAVOgAwIBAgIUde5G4y+mtbb0eRISc7vnINRbSXkwBQYDK2VwMEUxCzAJ\\n' +\n      'BgNVBAYTAkNaMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\\n' +\n      'dCBXaWRnaXRzIFB0eSBMdGQwIBcNMjIxMDExMTIyMTUzWhgPMjEyMjA5MTcxMjIx\\n' +\n      'NTNaMEUxCzAJBgNVBAYTAkNaMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQK\\n' +\n      'DBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwKjAFBgMrZXADIQCUFn0ZKG9tAS3L\\n' +\n      'Joaz7Q13hq6sfsRGrpQ4i9cZvn+1cKNTMFEwHQYDVR0OBBYEFAATzoAtBcYTcOdY\\n' +\n      'jkcQqsWXipnSMB8GA1UdIwQYMBaAFAATzoAtBcYTcOdYjkcQqsWXipnSMA8GA1Ud\\n' +\n      'EwEB/wQFMAMBAf8wBQYDK2VwA0EApfw+9jSO0x0IorDfdr5ZVGRBVgrfrd9XhxqQ\\n' +\n      'Krphj6cA4Ls9aMYAHf5w+OW9D/t3a9p6mYm78AKIdBsPEtT1AQ==\\n' +\n      '-----END CERTIFICATE-----\\n',\n  },\n  P256: {\n    jwk: {\n      crv: 'P-256',\n      d: 'WBuVA9Z5CghAbxxspv2j1SiHur5BIR-PSDedvQOzun8',\n      kty: 'EC',\n      x: '4CsFZERaJG_bMfC8AZNAtXbMT4hS6UHTQDsFDVFmZWs',\n      y: '-geyNWMPfctokhFckoSvx-tb_zfRoLZG1fqb3sqaNWw',\n    },\n    pkcs8:\n      '-----BEGIN PRIVATE KEY-----\\n' +\n      'MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgWBuVA9Z5CghAbxxs\\n' +\n      'pv2j1SiHur5BIR+PSDedvQOzun+hRANCAATgKwVkRFokb9sx8LwBk0C1dsxPiFLp\\n' +\n      'QdNAOwUNUWZla/oHsjVjD33LaJIRXJKEr8frW/830aC2RtX6m97KmjVs\\n' +\n      '-----END PRIVATE KEY-----\\n',\n    spki:\n      '-----BEGIN PUBLIC KEY-----\\n' +\n      'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4CsFZERaJG/bMfC8AZNAtXbMT4hS\\n' +\n      '6UHTQDsFDVFmZWv6B7I1Yw99y2iSEVyShK/H61v/N9GgtkbV+pveypo1bA==\\n' +\n      '-----END PUBLIC KEY-----\\n',\n    x509:\n      '-----BEGIN CERTIFICATE-----\\n' +\n      'MIIBCTCBsAIJAP3LUepKb7jlMAoGCCqGSM49BAMCMA0xCzAJBgNVBAYTAkNaMB4X\\n' +\n      'DTIyMTAxMTEyMjUwOVoXDTIzMTAwNjEyMjUwOVowDTELMAkGA1UEBhMCQ1owWTAT\\n' +\n      'BgcqhkjOPQIBBggqhkjOPQMBBwNCAATgKwVkRFokb9sx8LwBk0C1dsxPiFLpQdNA\\n' +\n      'OwUNUWZla/oHsjVjD33LaJIRXJKEr8frW/830aC2RtX6m97KmjVsMAoGCCqGSM49\\n' +\n      'BAMCA0gAMEUCIQDUxxIyJy8FQvrou0eGSLzAoNNKrYLIeI/OJzBIu6VkZwIgZvHb\\n' +\n      'W78UlObaQoVHfmO5TbgLpIEiskde4STWKDYIZmI=\\n' +\n      '-----END CERTIFICATE-----\\n',\n  },\n  P384: {\n    jwk: {\n      crv: 'P-384',\n      d: '5bt5RH4yyhwdtO2_gDHUgLn8aJqvlOaMHAznINEvkucDqiwrXL4ul42yNpx3biuM',\n      kty: 'EC',\n      x: 'sb8kfa8h1WbOGJC8lOMBEeXBYOM-EQNJjBSl7Ro5uiDI8Bk3cZpz0XPztPSHTXbw',\n      y: '4tyg6L2MAzZ53Sj7l8O7yYYGOYtpNmuoV8vDSjjk_X7KQY-s0G3uT30uoSWvN0vH',\n    },\n    pkcs8:\n      '-----BEGIN PRIVATE KEY-----\\n' +\n      'MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDDlu3lEfjLKHB207b+A\\n' +\n      'MdSAufxomq+U5owcDOcg0S+S5wOqLCtcvi6XjbI2nHduK4yhZANiAASxvyR9ryHV\\n' +\n      'Zs4YkLyU4wER5cFg4z4RA0mMFKXtGjm6IMjwGTdxmnPRc/O09IdNdvDi3KDovYwD\\n' +\n      'NnndKPuXw7vJhgY5i2k2a6hXy8NKOOT9fspBj6zQbe5PfS6hJa83S8c=\\n' +\n      '-----END PRIVATE KEY-----\\n',\n    spki:\n      '-----BEGIN PUBLIC KEY-----\\n' +\n      'MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEsb8kfa8h1WbOGJC8lOMBEeXBYOM+EQNJ\\n' +\n      'jBSl7Ro5uiDI8Bk3cZpz0XPztPSHTXbw4tyg6L2MAzZ53Sj7l8O7yYYGOYtpNmuo\\n' +\n      'V8vDSjjk/X7KQY+s0G3uT30uoSWvN0vH\\n' +\n      '-----END PUBLIC KEY-----\\n',\n    x509:\n      '-----BEGIN CERTIFICATE-----\\n' +\n      'MIIBRTCBzQIJAL/fppsFowYgMAoGCCqGSM49BAMCMA0xCzAJBgNVBAYTAkNaMB4X\\n' +\n      'DTIyMTAxMTEyMjUyMloXDTIzMTAwNjEyMjUyMlowDTELMAkGA1UEBhMCQ1owdjAQ\\n' +\n      'BgcqhkjOPQIBBgUrgQQAIgNiAASxvyR9ryHVZs4YkLyU4wER5cFg4z4RA0mMFKXt\\n' +\n      'Gjm6IMjwGTdxmnPRc/O09IdNdvDi3KDovYwDNnndKPuXw7vJhgY5i2k2a6hXy8NK\\n' +\n      'OOT9fspBj6zQbe5PfS6hJa83S8cwCgYIKoZIzj0EAwIDZwAwZAIwRc/RKmaCus0F\\n' +\n      '7/q6D5fPafPTU1iLIcgpdK9pS+7tsCY8UZF2j5fSTFbYG39XaMEYAjB+piZKxCxh\\n' +\n      '/9jkdLz6ax866tMp9hQNTYU98lO44IQXhcEqh13zR3Bek4KhEnpkWiE=\\n' +\n      '-----END CERTIFICATE-----\\n',\n  },\n  P521: {\n    jwk: {\n      crv: 'P-521',\n      d: 'Ae6uBN9ZtZD-yfB_--VPF_aEXTUlPENfj0mepT0chVvfi4BfWvs9NNCrv3YtWl1Q2FdYPop8Ch5_aiiiAH0QnmxH',\n      kty: 'EC',\n      x: 'AV6RoNRH5egig9TgU5CKHCf2H6XW7Rlqs_LZZKnQKJCZP_1x6RBw2Qgwwy8VCvUd_C_oxv45jU-boutt_ewcx7Wo',\n      y: 'Abou9L-hVPMkzKNpJPGvhWnAhHNL1DKsXTAty-BmNBZPGtEwWsod8Vv2KN8wcIc7ts3dLedTPIn77O63V32t-cc5',\n    },\n    pkcs8:\n      '-----BEGIN PRIVATE KEY-----\\n' +\n      'MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIB7q4E31m1kP7J8H/7\\n' +\n      '5U8X9oRdNSU8Q1+PSZ6lPRyFW9+LgF9a+z000Ku/di1aXVDYV1g+inwKHn9qKKIA\\n' +\n      'fRCebEehgYkDgYYABAFekaDUR+XoIoPU4FOQihwn9h+l1u0ZarPy2WSp0CiQmT/9\\n' +\n      'cekQcNkIMMMvFQr1Hfwv6Mb+OY1Pm6Lrbf3sHMe1qAG6LvS/oVTzJMyjaSTxr4Vp\\n' +\n      'wIRzS9QyrF0wLcvgZjQWTxrRMFrKHfFb9ijfMHCHO7bN3S3nUzyJ++zut1d9rfnH\\n' +\n      'OQ==\\n' +\n      '-----END PRIVATE KEY-----\\n',\n    spki:\n      '-----BEGIN PUBLIC KEY-----\\n' +\n      'MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBXpGg1Efl6CKD1OBTkIocJ/Yfpdbt\\n' +\n      'GWqz8tlkqdAokJk//XHpEHDZCDDDLxUK9R38L+jG/jmNT5ui62397BzHtagBui70\\n' +\n      'v6FU8yTMo2kk8a+FacCEc0vUMqxdMC3L4GY0Fk8a0TBayh3xW/Yo3zBwhzu2zd0t\\n' +\n      '51M8ifvs7rdXfa35xzk=\\n' +\n      '-----END PUBLIC KEY-----\\n',\n    x509:\n      '-----BEGIN CERTIFICATE-----\\n' +\n      'MIIBkDCB8wIJALGXk5Wy5tmGMAoGCCqGSM49BAMCMA0xCzAJBgNVBAYTAkNaMB4X\\n' +\n      'DTIyMTAxMTEyMjUzNFoXDTIzMTAwNjEyMjUzNFowDTELMAkGA1UEBhMCQ1owgZsw\\n' +\n      'EAYHKoZIzj0CAQYFK4EEACMDgYYABAFekaDUR+XoIoPU4FOQihwn9h+l1u0ZarPy\\n' +\n      '2WSp0CiQmT/9cekQcNkIMMMvFQr1Hfwv6Mb+OY1Pm6Lrbf3sHMe1qAG6LvS/oVTz\\n' +\n      'JMyjaSTxr4VpwIRzS9QyrF0wLcvgZjQWTxrRMFrKHfFb9ijfMHCHO7bN3S3nUzyJ\\n' +\n      '++zut1d9rfnHOTAKBggqhkjOPQQDAgOBiwAwgYcCQgCfBR/x6atEB5KAaYmNOiKm\\n' +\n      'OHhQISZU62ayPDipxsXf9vh4OK5WDdI4SmC1du07kAlwa2tFVSvz7vkMXGGXVYBr\\n' +\n      'PQJBSjIXjpo07m26F0Jmv0OVX2on98+GN7xP8pRCviAuQj8UWKIQvwnj3esymVWb\\n' +\n      'kmEjhnWo8H38/2wddwksoxHvinU=\\n' +\n      '-----END CERTIFICATE-----\\n',\n  },\n  RSA: {\n    jwk: {\n      d: 'B2Uk38NDKaU7ISmT2nqrQSuC5-fvZSJz4XHaWlVm-7lSV4OE1q7Z2fve9c93Q6Bkb8r6gwpTX_AFcWu6NbJmkascpOa5FhhGjffhxFxCKMRkT6ERt6PanHvLGKrk8UJsibjH_ds7UihOH-jd046jtoJjYHv7hmT3Rf0uttzGd6PDMHaZfp8xCjbAYZUFqW91O0hw3x1ZESsWyAS353JIjePzK5JmY7T7jbd-t6_M-u8i8-lv60Q8mvY0Np8iZadA3dFntIl0J4pwHGQGCC45mCAFIs6dgbVvyor7Eg82oDXHH3oOXIwYDi64Aw91EqxF8CdEByIV3_GphBzikEtTDw',\n      dp: 'lRCClYTQvzgsVoVJjdyADVtceVsH7KfwpFxnrot_V40XJkUmiHj2yWGld8kB78q66faOavY-TFpmFlo-BQpEiXCDGzCqNCLJ-lF_ZnWyARfQHBBQPFHH2MqaNiS29yjpt7V4vc4z1DL_v5CaiR1wq9AZTABIUf8l2dAkHFrSTKk',\n      dq: 'DMfbSrlSf71Ng5WuZxtENbQOSTOOP3rIyYibdPzbjJyb5raj09XQW_EJiaM45qbSwJfzFOnrFrQcoOJYmQTlHkVMcnXis2r1WXT0So32_D_kDevNZjHFG4PvqnK4ToV_GCGy1IbG4vHdjyMmHtG00zy9-02j7WV8-OerFP7QIAk',\n      e: 'AQAB',\n      kty: 'RSA',\n      n: 'wINok6pE72n8ry3P6EIR-4B9oJmudAK_Q9mKkbG7eZlnP2Nvn5Fq6IhbsLn-ygT9OO_PzT23UdkxnjF8DUgSt7fVStQ40z4_lHVSPVIQeeDkML9Pipu1zUx6RqweUZdXnoN0JFNM93iUfJEvEukYxrWAeFVrRL2DU2E8DSrlJUyCO-c2NaO3YFsFdowW8pviMAnOs39VZNemiQtT-D4fg48dRX5bkrzjaRymhY7bWGelts0FhrNb6Jy-WMnSPxqpozbQ0ODI4kGQYSrKiUNLDfnSUAR-o5I4Hp2bkOrXt6lLccNu0PpPksVAWzTLyFtixxC9APKyUJSKQ7zNpKhqwQ',\n      p: '4EqeWf4b6BJ_7v0Dwa_prSvDRylomA_IZpSDP_1Cqy24IFP1dBzdqm0gYbLNq3xQJkhptbBbC7xOPt4Zz0n-wJOHOkGf31m5-Gc4BiR9fTOEdFRtEQJyLfPu-7D9UbJH_bz_zsOQw9TDzllZp1H9X87AzkkkMfqjinxC749tJ1s',\n      q: '27qzE-tl4V0HT_8PGI6YG2rphRfe5PArRSFgRmampXve6d_vgu5IpZEoNG7YGcT_J6tcdxF19-M2VEeNyqTPl2X91ba-RjkAByOTcT4n57-M4aK9yJt8un8BPBBNco42GmDnb5ZkC1UwJrrHc8QSmTjDBmvvjJYNUseWeYvCrRM',\n      qi: 'yjY4FSvy_h8BXcbZJq1rLpMiEAqI3yMZ2wK8THJSfD37xbhil5PrDzzOluM_qkaC1aKTTAksFsx8f5AOEePCyjW095OBQe379EizSIC_EnByBdkfms8u5VOOKrZUI6I024QMhFsWCodaDDoNg-xXGD-viRtxpam9ZxVnyLRDOdg',\n    },\n    pkcs8:\n      '-----BEGIN PRIVATE KEY-----\\n' +\n      'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDAg2iTqkTvafyv\\n' +\n      'Lc/oQhH7gH2gma50Ar9D2YqRsbt5mWc/Y2+fkWroiFuwuf7KBP0478/NPbdR2TGe\\n' +\n      'MXwNSBK3t9VK1DjTPj+UdVI9UhB54OQwv0+Km7XNTHpGrB5Rl1eeg3QkU0z3eJR8\\n' +\n      'kS8S6RjGtYB4VWtEvYNTYTwNKuUlTII75zY1o7dgWwV2jBbym+IwCc6zf1Vk16aJ\\n' +\n      'C1P4Ph+Djx1FfluSvONpHKaFjttYZ6W2zQWGs1vonL5YydI/GqmjNtDQ4MjiQZBh\\n' +\n      'KsqJQ0sN+dJQBH6jkjgenZuQ6te3qUtxw27Q+k+SxUBbNMvIW2LHEL0A8rJQlIpD\\n' +\n      'vM2kqGrBAgMBAAECggEAB2Uk38NDKaU7ISmT2nqrQSuC5+fvZSJz4XHaWlVm+7lS\\n' +\n      'V4OE1q7Z2fve9c93Q6Bkb8r6gwpTX/AFcWu6NbJmkascpOa5FhhGjffhxFxCKMRk\\n' +\n      'T6ERt6PanHvLGKrk8UJsibjH/ds7UihOH+jd046jtoJjYHv7hmT3Rf0uttzGd6PD\\n' +\n      'MHaZfp8xCjbAYZUFqW91O0hw3x1ZESsWyAS353JIjePzK5JmY7T7jbd+t6/M+u8i\\n' +\n      '8+lv60Q8mvY0Np8iZadA3dFntIl0J4pwHGQGCC45mCAFIs6dgbVvyor7Eg82oDXH\\n' +\n      'H3oOXIwYDi64Aw91EqxF8CdEByIV3/GphBzikEtTDwKBgQDgSp5Z/hvoEn/u/QPB\\n' +\n      'r+mtK8NHKWiYD8hmlIM//UKrLbggU/V0HN2qbSBhss2rfFAmSGm1sFsLvE4+3hnP\\n' +\n      'Sf7Ak4c6QZ/fWbn4ZzgGJH19M4R0VG0RAnIt8+77sP1Rskf9vP/Ow5DD1MPOWVmn\\n' +\n      'Uf1fzsDOSSQx+qOKfELvj20nWwKBgQDburMT62XhXQdP/w8YjpgbaumFF97k8CtF\\n' +\n      'IWBGZqale97p3++C7kilkSg0btgZxP8nq1x3EXX34zZUR43KpM+XZf3Vtr5GOQAH\\n' +\n      'I5NxPifnv4zhor3Im3y6fwE8EE1yjjYaYOdvlmQLVTAmusdzxBKZOMMGa++Mlg1S\\n' +\n      'x5Z5i8KtEwKBgQCVEIKVhNC/OCxWhUmN3IANW1x5Wwfsp/CkXGeui39XjRcmRSaI\\n' +\n      'ePbJYaV3yQHvyrrp9o5q9j5MWmYWWj4FCkSJcIMbMKo0Isn6UX9mdbIBF9AcEFA8\\n' +\n      'UcfYypo2JLb3KOm3tXi9zjPUMv+/kJqJHXCr0BlMAEhR/yXZ0CQcWtJMqQKBgAzH\\n' +\n      '20q5Un+9TYOVrmcbRDW0Dkkzjj96yMmIm3T824ycm+a2o9PV0FvxCYmjOOam0sCX\\n' +\n      '8xTp6xa0HKDiWJkE5R5FTHJ14rNq9Vl09EqN9vw/5A3rzWYxxRuD76pyuE6Ffxgh\\n' +\n      'stSGxuLx3Y8jJh7RtNM8vftNo+1lfPjnqxT+0CAJAoGBAMo2OBUr8v4fAV3G2Sat\\n' +\n      'ay6TIhAKiN8jGdsCvExyUnw9+8W4YpeT6w88zpbjP6pGgtWik0wJLBbMfH+QDhHj\\n' +\n      'wso1tPeTgUHt+/RIs0iAvxJwcgXZH5rPLuVTjiq2VCOiNNuEDIRbFgqHWgw6DYPs\\n' +\n      'Vxg/r4kbcaWpvWcVZ8i0QznY\\n' +\n      '-----END PRIVATE KEY-----\\n',\n    spki:\n      '-----BEGIN PUBLIC KEY-----\\n' +\n      'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwINok6pE72n8ry3P6EIR\\n' +\n      '+4B9oJmudAK/Q9mKkbG7eZlnP2Nvn5Fq6IhbsLn+ygT9OO/PzT23UdkxnjF8DUgS\\n' +\n      't7fVStQ40z4/lHVSPVIQeeDkML9Pipu1zUx6RqweUZdXnoN0JFNM93iUfJEvEukY\\n' +\n      'xrWAeFVrRL2DU2E8DSrlJUyCO+c2NaO3YFsFdowW8pviMAnOs39VZNemiQtT+D4f\\n' +\n      'g48dRX5bkrzjaRymhY7bWGelts0FhrNb6Jy+WMnSPxqpozbQ0ODI4kGQYSrKiUNL\\n' +\n      'DfnSUAR+o5I4Hp2bkOrXt6lLccNu0PpPksVAWzTLyFtixxC9APKyUJSKQ7zNpKhq\\n' +\n      'wQIDAQAB\\n' +\n      '-----END PUBLIC KEY-----\\n',\n    x509:\n      '-----BEGIN CERTIFICATE-----\\n' +\n      'MIICljCCAX4CCQDz0yP7UQpRIjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJD\\n' +\n      'WjAeFw0yMjEwMTExMjI2NTVaFw0yMzEwMDYxMjI2NTVaMA0xCzAJBgNVBAYTAkNa\\n' +\n      'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwINok6pE72n8ry3P6EIR\\n' +\n      '+4B9oJmudAK/Q9mKkbG7eZlnP2Nvn5Fq6IhbsLn+ygT9OO/PzT23UdkxnjF8DUgS\\n' +\n      't7fVStQ40z4/lHVSPVIQeeDkML9Pipu1zUx6RqweUZdXnoN0JFNM93iUfJEvEukY\\n' +\n      'xrWAeFVrRL2DU2E8DSrlJUyCO+c2NaO3YFsFdowW8pviMAnOs39VZNemiQtT+D4f\\n' +\n      'g48dRX5bkrzjaRymhY7bWGelts0FhrNb6Jy+WMnSPxqpozbQ0ODI4kGQYSrKiUNL\\n' +\n      'DfnSUAR+o5I4Hp2bkOrXt6lLccNu0PpPksVAWzTLyFtixxC9APKyUJSKQ7zNpKhq\\n' +\n      'wQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCgIGx+4WgwLtSGAxquNk7pMoewqyCx\\n' +\n      'PO1v/3Snte5sHcn2+yBHaVeRrbnvniJIUNWnvGs/MuGA5fhsSgRBeXqOsLq0eprX\\n' +\n      'YfPG7PG532NoaZ97Gp9X/YH3tTLCh/gyp0kQ2R0eci6f3J7nDzSPazHskEGTujHS\\n' +\n      'uSczHvQsD8HdAd2CsZLPp02NgKhiG4VwMP2CeaUTG/62eZp/fGEAAqrXn4YoHsnY\\n' +\n      'DPCORtzlkel/kV8r0/ktXt+fWoPIpn3dUaHDwi9V9RMkML9IMyLYFfLnpfxFMqdg\\n' +\n      '7KWOOFnaMmoDLlICZk7Ym3SjNt86hzmJ+eWiUuHAdFN4PeKj9wXd0t90\\n' +\n      '-----END CERTIFICATE-----\\n',\n  },\n  X25519: {\n    jwk: {\n      crv: 'X25519',\n      d: 'WCN6m3ZhxgzgsmacDlbq_O347na7uQe6cW8T6ZJ19mw',\n      kty: 'OKP',\n      x: 'aq1ZuCRIE3XXXcRpbC_txuESJ4KFH8VwQlz1nVa8Ugk',\n    },\n    pkcs8:\n      '-----BEGIN PRIVATE KEY-----\\n' +\n      'MC4CAQAwBQYDK2VuBCIEIFgjept2YcYM4LJmnA5W6vzt+O52u7kHunFvE+mSdfZs\\n' +\n      '-----END PRIVATE KEY-----\\n',\n    spki:\n      '-----BEGIN PUBLIC KEY-----\\n' +\n      'MCowBQYDK2VuAyEAaq1ZuCRIE3XXXcRpbC/txuESJ4KFH8VwQlz1nVa8Ugk=\\n' +\n      '-----END PUBLIC KEY-----\\n',\n    x509: undefined,\n  },\n  'ML-DSA-44': {\n    jwk: {\n      kty: 'AKP',\n      alg: 'ML-DSA-44',\n      pub: 'fYmD1Rx_jkoW9KG7Bs_5zyYEiWEZs15tYBxNdKq9NircZnvZBwwwaGbj0UsxJNc4Dyfp2IFAZZPO3rFCSUdpXHPrGRHwIVMzwiwfu2V7V02xoheW4mrkPThA3JRJSmNdsx6YGu37MaeJkIk6AlUexo46JfGrkRXZp_IyZxiL_L2dPrfwx-32j7WFI5sBadp7cDWfNkJjdQwW4puTe5Rw7h16GHb-DMOAKpfeMHujh7IYHuLCU6lVi90j1m8Ru0dxdmeQ1eY1vDnO7fNQKfzOLhpUNnj7BBZ24GTqFc-SN5HDCSCsSGKScTYYBwiSVTdSGG1GNqIiN2FgE4z1Jj6JFVB_OIUnl4sKbb3m8kB0BwtUPbkC0FVokGRUEGt6ba1Pc_IMpB5Gs3g9PFREI_C9o1yVW3NS2PzH_Vk4Tpf0N1K1kzIK_3IqekLfyqXmVDNsOovsS7Sw9TdmdWUNGRmhXFKRkex5VjpMIx7OwBGsYJCc4FhauWdrVtbkvHGggSpsla73ZcA4Vzh7aq47LMv0KS2YLp-DMn7SEohPHGg74118eLLn88yptxwtwt1dBFj8BKUfPrytuN1EIRQy34hwbkBLN9wDqhgn3Z3fvksRvmgN_4ZQ8YjeD-H3OFh5WJ_Rd66wHSl-YFat-_JF4UPcdlkNUbxPvDi5VL909Pe3VlwEZhT5otdtXQX4U3dUfqWKEh2kN0Q2lo8wbf3OMmBOFTfyX0eYa_5088ZnJvvliefn-TCDyc6WlcZrNqwBOF8N8-IN3b_8RPq-RuV8-mK-M83Hi4ElQB7Z44eZMmfUwFrozEG4Wq2K6MwQ_edG4dWeUVMCloTpGDFOtlLQlDoAN4m_sS2Lbwm_3ra29noUcK8_j10yy-hENE2Yluh1pIL-GoWZj3uYO-rEKVbszaagdE0DJ_uQcHUdNnBHKn64-cQ6xihXzxaeHx9OxkWWMKbzLtKpuYDK_X7EVvm8YTjl_oTsr2SWT2usjNJko32DhRV-OXLKKHo5FJpCy2bGFLXGG26CglUvgZQ2dyXiWeGVNKffOv1cQ5R_RlU2MpLiZ1bigy9hh4lu_XAHLfjQfhf71jeMuF4nEBWV-YOAjDTaDB2hcGqv_XcGXcmLWHqOWgc5Mb6lkb2zYs_oyOskmyFx6C0P7UrV8kCiN4zbuTqZNdNjlWL_QJUmU3vk6CpNa0XN1M3sLjZpOEsaqgRVPLcIDH-juVhyWiymuxe-8yNCOFSKxhscew08EQ9DEckP_iIA8qU2gcreHtvAS5VA5Emz1K2ypYe6oS3ogP-CX4nOAEfvjsb1HHJoclgiwjL1BtCLFgOE-0vn1M-nVOE6WbHGHoNKMJMHP2a3HQC7DmDfSOw5P6Cj5X7QVqhCY6tAGZWEPu3hUssp7K5UJePEdBn_LrErt4ucyXW6y1PAA2Fn8EuHaRyf2ggibDGnzq8E15m_R4LMvZAuGR0bN9jBTlm_x4ZQMqFwKkIdllkN1QTErazOyNsgU6fhA_20h5EIYT6-LqXr_Otj3Kp8MkJB9c3XNGoo5sbHTQCt0VNOHoxCFP_swiAJLtm743eOsI1M6naWLIqPagSCioosAvJYowypJQGvM-N3hBu8KUr0f911KRN7WqTAXTOHZ_vvTqcWKet0dFdh1EHuP3TrU8hSMciaphGvuK93T3gaWuJ6lcCkQndWvEo9S6FQB7eLU_ALKOQ3ROybUUkXgfyTkWDPxbHdeJCgMRv6Ig1PShPyxYb4ig',\n      priv: '273AhMPiZWLlSQCY41yi1fMj6xavGH0btB23zMhI1uY',\n    },\n    pkcs8: `-----BEGIN PRIVATE KEY-----\nMDQCAQAwCwYJYIZIAWUDBAMRBCKAINu9wITD4mVi5UkAmONcotXzI+sWrxh9G7Qd\nt8zISNbm\n-----END PRIVATE KEY-----`,\n    spki: `-----BEGIN PUBLIC KEY-----\nMIIFMjALBglghkgBZQMEAxEDggUhAH2Jg9Ucf45KFvShuwbP+c8mBIlhGbNebWAc\nTXSqvTYq3GZ72QcMMGhm49FLMSTXOA8n6diBQGWTzt6xQklHaVxz6xkR8CFTM8Is\nH7tle1dNsaIXluJq5D04QNyUSUpjXbMemBrt+zGniZCJOgJVHsaOOiXxq5EV2afy\nMmcYi/y9nT638Mft9o+1hSObAWnae3A1nzZCY3UMFuKbk3uUcO4dehh2/gzDgCqX\n3jB7o4eyGB7iwlOpVYvdI9ZvEbtHcXZnkNXmNbw5zu3zUCn8zi4aVDZ4+wQWduBk\n6hXPkjeRwwkgrEhiknE2GAcIklU3UhhtRjaiIjdhYBOM9SY+iRVQfziFJ5eLCm29\n5vJAdAcLVD25AtBVaJBkVBBrem2tT3PyDKQeRrN4PTxURCPwvaNclVtzUtj8x/1Z\nOE6X9DdStZMyCv9yKnpC38ql5lQzbDqL7Eu0sPU3ZnVlDRkZoVxSkZHseVY6TCMe\nzsARrGCQnOBYWrlna1bW5LxxoIEqbJWu92XAOFc4e2quOyzL9CktmC6fgzJ+0hKI\nTxxoO+NdfHiy5/PMqbccLcLdXQRY/ASlHz68rbjdRCEUMt+IcG5ASzfcA6oYJ92d\n375LEb5oDf+GUPGI3g/h9zhYeVif0XeusB0pfmBWrfvyReFD3HZZDVG8T7w4uVS/\ndPT3t1ZcBGYU+aLXbV0F+FN3VH6lihIdpDdENpaPMG39zjJgThU38l9HmGv+dPPG\nZyb75Ynn5/kwg8nOlpXGazasAThfDfPiDd2//ET6vkblfPpivjPNx4uBJUAe2eOH\nmTJn1MBa6MxBuFqtiujMEP3nRuHVnlFTApaE6RgxTrZS0JQ6ADeJv7Eti28Jv962\ntvZ6FHCvP49dMsvoRDRNmJbodaSC/hqFmY97mDvqxClW7M2moHRNAyf7kHB1HTZw\nRyp+uPnEOsYoV88Wnh8fTsZFljCm8y7SqbmAyv1+xFb5vGE45f6E7K9klk9rrIzS\nZKN9g4UVfjlyyih6ORSaQstmxhS1xhtugoJVL4GUNncl4lnhlTSn3zr9XEOUf0ZV\nNjKS4mdW4oMvYYeJbv1wBy340H4X+9Y3jLheJxAVlfmDgIw02gwdoXBqr/13Bl3J\ni1h6jloHOTG+pZG9s2LP6MjrJJshcegtD+1K1fJAojeM27k6mTXTY5Vi/0CVJlN7\n5OgqTWtFzdTN7C42aThLGqoEVTy3CAx/o7lYclosprsXvvMjQjhUisYbHHsNPBEP\nQxHJD/4iAPKlNoHK3h7bwEuVQORJs9StsqWHuqEt6ID/gl+JzgBH747G9RxyaHJY\nIsIy9QbQixYDhPtL59TPp1ThOlmxxh6DSjCTBz9mtx0Auw5g30jsOT+go+V+0Fao\nQmOrQBmVhD7t4VLLKeyuVCXjxHQZ/y6xK7eLnMl1ustTwANhZ/BLh2kcn9oIImwx\np86vBNeZv0eCzL2QLhkdGzfYwU5Zv8eGUDKhcCpCHZZZDdUExK2szsjbIFOn4QP9\ntIeRCGE+vi6l6/zrY9yqfDJCQfXN1zRqKObGx00ArdFTTh6MQhT/7MIgCS7Zu+N3\njrCNTOp2liyKj2oEgoqKLALyWKMMqSUBrzPjd4QbvClK9H/ddSkTe1qkwF0zh2f7\n706nFinrdHRXYdRB7j9061PIUjHImqYRr7ivd094GlriepXApEJ3VrxKPUuhUAe3\ni1PwCyjkN0Tsm1FJF4H8k5Fgz8Wx3XiQoDEb+iINT0oT8sWG+Io=\n-----END PUBLIC KEY-----\n`,\n  },\n  'ML-DSA-65': {\n    jwk: {\n      kty: 'AKP',\n      alg: 'ML-DSA-65',\n      pub: 'hxPP5LvG83t2fJyfA1TUssJK_ydrzryrCHGZuKFxmnl5Y3sxHRCPW_JpHEoiIgR6kgELnwibZnueax1zFerTOTA7o0NwXHFiaEB-8AmqJI93DkvtbUOSTCixa3admQBKW_PtgMCVtaEVuuvCuOEFhOyuZkyfvnpBwUKOkz3t-O1wpgrSmf-rdPXOEv8YcsSn-xfLYPSLzPCnt7gnIX_fwtkgnXjref-QqjFKlKZE2e7MkmHeViJ4iGy78r3UzVhBHsmFGC0ZNc8-iT3muH5Sn0SXmNq-F2EoerWLIAsPxL2KE6UrqPAwTbHn1B5sAGWvhsVVLlFPI1s1JLVLBNRJ5vhif525xNIpMAMuAZrteD827pve3zQo9_GHjWgykj9VzM9PEcVmVqxZ5u41kUXsM4PWZF29Oh2sYsmJ2LdiJ9RcA91vRLG2DqEYm-V5JwIz8uxL17DUsEC7zYthvtqGASq05CbfPTBev33rQUv4H0Etz99U89WooTk0FisHDz1uEUilU_VY1tN5byIDitXNf0jnz3SIHDUUZARn7ll0YwO0jtksT68sQW3Liy6Exhlp1td0so2qZUrbVZasjyCOVuibwbwvrdpP3QRsoG5UqkAqk8Rm2iCpdQSg87pswOscgA8AC8TczGHNfXc9PqzAmbsEPKvmZuE60HLGzqpRqFULf3nyYUQUqbdmKJsKQ29LXeDVbyy3-fkTUDuYqNC2tBY7PkzHJSA9Z4hDC_BHEFxcelibScSNyf7y4lDVWnuJMXpQ0WRh3UkUPa007IerhixwxvBvFXQR-ytYinixvjirlcEF1wQI1DzE8KjOXYYuFPS4Yl8HeZHQ-64Q0RuxlKIRP3YvjZWh4IDVvEVs5ZLzZPbE3Twe0N5a7iCu0BzZWTeHNbcMoViFyJTpec2w3vVHeI4PJB-5HeI8xuh-9y8ytTau8QtMe4thoROoajizDQLrkw3e6ryJJ3R84i0oni4vmZWyLDilwcLqPOkQJCIDMjq7exdmVX5t3DtAW4F6Coz0z3sf7tGlSMVxA7izCoVbG0y2_l1P2h7fWBuEPT7PWlMdPqu9Pj5jqXY6jJ0nkaR_pp7dDhO1HKae5edcBYunHZqVQQjRZ_DvKzbPrDk5t6Xq9fdSkiAeP3B4qn5uU-nx7OaX7DRoVEnbbiEDynIRPSEY-Ts3alPJtBv8zuzaGNyX05Z9MyZ0w-VlC-WxOBdVEsIAp_4uJ3kQ3UsfE9DLJH8WPuDI4t4i2VnNNyFlI0XSUocc_0rWgqp2I1UzSzkVbklwkuFywPI645u4G2XAlfdd_wpjFGC-IUPXgpeSfspPwW15sBP-ITS-gwtvfzQVLpRS0euzN97xo_GMhNPZ4bW-YyZt8z_R8bsQ8ktfoP-5RUV-yzYDt0tA01QJsZdBLf5J_H7qP8l4c8V4hPe_CFL032obbxmAnVPAP69u2SaMBlL8azjk4wGVFQpQp1JqMJCao2W8ZImCVegkPZxhGbx0nkgVfyFx4ihMeDNM288JbGC4CGON8C02Q84rQzhwzZE83Y9rSe1Bb0fUMHMu6ihD5jLdeltuBL4ZdJlKgL24KZK5o5pq4_l9SyzGAjB1KAQnClNOB1SxV89CtILu-65wb17s0z3qw2-NF0B6UVlGQFebjbSyLQv2ARaETh_8cBiPugVMgBIV3K1KBwNyWejyI1ZDCssvIZHJCF2SRW3HmJerTiB23eGHFYKSLdxW7LEzoHIc2xZEc3pwR43gavjeoL0pNc-HNFV_c19wiH7Tnw3IHld_FfTqAIPnqKMNIY7D_D0DmFNTOdnzcipqKxUB0Avc-wr8Fz0gjeRpLH2iDSCJWtvWjoeYvHTktGsblDAM5j9xznwEvZfQvj8fTUnFxl3clkD6e9V1jrDQDkXfOtl-bDIv9PtMwamfJFu-z2ubF-gKytUewPNo10uhwr2TDNdUayCZDR2T3HoRLN8goIw2bFoPJ98LoPcSukEvKABjH0DiHNeqFELNZPx_uCx5N-YFkUZxHWA1QUoGhqQ3REtcT3c-SZf_TDFOPvws6bmwt4lcWpLmubOAJLFt6J8m8HCkVUshRdFzvHQm_0JEvA3JtyXZzvsPUv5njdk0nxTZktvsnqX054RQk5x8U-lBY-bK3uMOoFnHju45LMoHCUgGJi22eUm7nLGZEh84ZAbNlPLXpfavXvPJh21OW5EOAeuQ-yWNHY2xbmAiHNnb-J2VpZc1Vy82sxn8umFtKduuQuIQMOsf4qHqj5MzDY_1NjrM4Wm7XAiLC4MpQ22w9PWNQXSZWvo2fj8WUnfEibpgyRkoD2P25GRQqsRJ3-Ykl5bm_2Vfe6i3oXHOwQwZwKGXfAqXyo4iU1UI7e-qC4sj5U64oB_A_NSBaJJrZoQ2fVeGTnFxA4QMMoWCT0VlwBXK0B3jht8Xal3WcI-i9ctQB1-GrmwwgG2ttePHt1IKy69bSZE3FLkFicaHg6VxypG6ef8rVsmMrfpTATOnF5_iEaLNY9428HHGW0iz4vXwaE-MkYy7NK2KMPFiCB0ec9OjIROwayK4LREv4qknWHnVQRSm25Rr9DcVFXKj16Au7X1hv7TuVH7h25U',\n      priv: '1X9VEr_iXMRwBvnSytEmHrtA-DpD6FWAUqMrDNlJVBg',\n    },\n    pkcs8: `-----BEGIN PRIVATE KEY-----\nMDQCAQAwCwYJYIZIAWUDBAMSBCKAINV/VRK/4lzEcAb50srRJh67QPg6Q+hVgFKj\nKwzZSVQY\n-----END PRIVATE KEY-----`,\n    spki: `-----BEGIN PUBLIC KEY-----\nMIIHsjALBglghkgBZQMEAxIDggehAIcTz+S7xvN7dnycnwNU1LLCSv8na868qwhx\nmbihcZp5eWN7MR0Qj1vyaRxKIiIEepIBC58Im2Z7nmsdcxXq0zkwO6NDcFxxYmhA\nfvAJqiSPdw5L7W1DkkwosWt2nZkASlvz7YDAlbWhFbrrwrjhBYTsrmZMn756QcFC\njpM97fjtcKYK0pn/q3T1zhL/GHLEp/sXy2D0i8zwp7e4JyF/38LZIJ1463n/kKox\nSpSmRNnuzJJh3lYieIhsu/K91M1YQR7JhRgtGTXPPok95rh+Up9El5javhdhKHq1\niyALD8S9ihOlK6jwME2x59QebABlr4bFVS5RTyNbNSS1SwTUSeb4Yn+ducTSKTAD\nLgGa7Xg/Nu6b3t80KPfxh41oMpI/VczPTxHFZlasWebuNZFF7DOD1mRdvTodrGLJ\nidi3YifUXAPdb0Sxtg6hGJvleScCM/LsS9ew1LBAu82LYb7ahgEqtOQm3z0wXr99\n60FL+B9BLc/fVPPVqKE5NBYrBw89bhFIpVP1WNbTeW8iA4rVzX9I5890iBw1FGQE\nZ+5ZdGMDtI7ZLE+vLEFty4suhMYZadbXdLKNqmVK21WWrI8gjlbom8G8L63aT90E\nbKBuVKpAKpPEZtogqXUEoPO6bMDrHIAPAAvE3MxhzX13PT6swJm7BDyr5mbhOtBy\nxs6qUahVC3958mFEFKm3ZiibCkNvS13g1W8st/n5E1A7mKjQtrQWOz5MxyUgPWeI\nQwvwRxBcXHpYm0nEjcn+8uJQ1Vp7iTF6UNFkYd1JFD2tNOyHq4YscMbwbxV0Efsr\nWIp4sb44q5XBBdcECNQ8xPCozl2GLhT0uGJfB3mR0PuuENEbsZSiET92L42VoeCA\n1bxFbOWS82T2xN08HtDeWu4grtAc2Vk3hzW3DKFYhciU6XnNsN71R3iODyQfuR3i\nPMbofvcvMrU2rvELTHuLYaETqGo4sw0C65MN3uq8iSd0fOItKJ4uL5mVsiw4pcHC\n6jzpECQiAzI6u3sXZlV+bdw7QFuBegqM9M97H+7RpUjFcQO4swqFWxtMtv5dT9oe\n31gbhD0+z1pTHT6rvT4+Y6l2OoydJ5Gkf6ae3Q4TtRymnuXnXAWLpx2alUEI0Wfw\n7ys2z6w5Obel6vX3UpIgHj9weKp+blPp8ezml+w0aFRJ224hA8pyET0hGPk7N2pT\nybQb/M7s2hjcl9OWfTMmdMPlZQvlsTgXVRLCAKf+Lid5EN1LHxPQyyR/Fj7gyOLe\nItlZzTchZSNF0lKHHP9K1oKqdiNVM0s5FW5JcJLhcsDyOuObuBtlwJX3Xf8KYxRg\nviFD14KXkn7KT8FtebAT/iE0voMLb380FS6UUtHrszfe8aPxjITT2eG1vmMmbfM/\n0fG7EPJLX6D/uUVFfss2A7dLQNNUCbGXQS3+Sfx+6j/JeHPFeIT3vwhS9N9qG28Z\ngJ1TwD+vbtkmjAZS/Gs45OMBlRUKUKdSajCQmqNlvGSJglXoJD2cYRm8dJ5IFX8h\nceIoTHgzTNvPCWxguAhjjfAtNkPOK0M4cM2RPN2Pa0ntQW9H1DBzLuooQ+Yy3Xpb\nbgS+GXSZSoC9uCmSuaOaauP5fUssxgIwdSgEJwpTTgdUsVfPQrSC7vuucG9e7NM9\n6sNvjRdAelFZRkBXm420si0L9gEWhE4f/HAYj7oFTIASFdytSgcDclno8iNWQwrL\nLyGRyQhdkkVtx5iXq04gdt3hhxWCki3cVuyxM6ByHNsWRHN6cEeN4Gr43qC9KTXP\nhzRVf3NfcIh+058NyB5XfxX06gCD56ijDSGOw/w9A5hTUznZ83IqaisVAdAL3PsK\n/Bc9II3kaSx9og0giVrb1o6HmLx05LRrG5QwDOY/cc58BL2X0L4/H01JxcZd3JZA\n+nvVdY6w0A5F3zrZfmwyL/T7TMGpnyRbvs9rmxfoCsrVHsDzaNdLocK9kwzXVGsg\nmQ0dk9x6ESzfIKCMNmxaDyffC6D3ErpBLygAYx9A4hzXqhRCzWT8f7gseTfmBZFG\ncR1gNUFKBoakN0RLXE93PkmX/0wxTj78LOm5sLeJXFqS5rmzgCSxbeifJvBwpFVL\nIUXRc7x0Jv9CRLwNybcl2c77D1L+Z43ZNJ8U2ZLb7J6l9OeEUJOcfFPpQWPmyt7j\nDqBZx47uOSzKBwlIBiYttnlJu5yxmRIfOGQGzZTy16X2r17zyYdtTluRDgHrkPsl\njR2NsW5gIhzZ2/idlaWXNVcvNrMZ/LphbSnbrkLiEDDrH+Kh6o+TMw2P9TY6zOFp\nu1wIiwuDKUNtsPT1jUF0mVr6Nn4/FlJ3xIm6YMkZKA9j9uRkUKrESd/mJJeW5v9l\nX3uot6FxzsEMGcChl3wKl8qOIlNVCO3vqguLI+VOuKAfwPzUgWiSa2aENn1Xhk5x\ncQOEDDKFgk9FZcAVytAd44bfF2pd1nCPovXLUAdfhq5sMIBtrbXjx7dSCsuvW0mR\nNxS5BYnGh4OlccqRunn/K1bJjK36UwEzpxef4hGizWPeNvBxxltIs+L18GhPjJGM\nuzStijDxYggdHnPToyETsGsiuC0RL+KpJ1h51UEUptuUa/Q3FRVyo9egLu19Yb+0\n7lR+4duV\n-----END PUBLIC KEY-----\n`,\n  },\n  'ML-DSA-87': {\n    jwk: {\n      kty: 'AKP',\n      alg: 'ML-DSA-87',\n      pub: 'DZXqaBATRN0GRtigxzkLxp7C9fFYxI7Gl-tdfXqJHbzVCTTvRfRwZcu3YmpsUYXBdX2pVsQ51QlqxMslKBRmfNCanBLcfd57qoEIb0K6GIKZGHxlsr9aXNjEGcKMo0ICon0LYTvTWrl72Oz-2yEA_abPK3_dBUFGAYQ6kOQhAHcT1CMmTTck23PnEd5WUpYfZOA9giFX9dNVrrdFWczj_vDOty81ObNKsxfVWT1nG7c60UCJxb2c2tMrBx3rp7Hfc_aOg54W5KHocJi0Eai0ok4buySTe0UCSCUTkeoCcdiABgOFBiXRYzpm3Lz4uot6hSgFpuh67fE9Zpgtn64vfI-O1mgcPrPPpd3yA92Jrq-dvXuM55w1RmA_hha3U5Sh2vm0tD1U57q945UppFReIv_8NAKBkxQ_vHil7ySm-m7IAM-sTUY86_IqMZqisxoz7Ff7ZR2vIiUm3-L0ow4B8uPsCv2ZlUoVXvMF6XQiOHsgqgP1rfH8DmfmPFudwiXrAW6wEmi10skPmkN92aC3TPG6nmaNryQ7f8J82yVmGxW9U7zMbg21qNkRGBi_1YwEt6D8V2pUWv5U1a4p4-Ma0f4uQG4g0odM-WGomlh7pZWZf3sffiPXk9wBrGisxtCJuaB5vtkheWxpEfWqnhc3QdOWfrsRg6P1h7M95SNVW0U8A38wwrqPOpzEnckCVdCrZz2b2KVln6a4twfINg1-3lEZR4rkEmTaTYlLFlXzbRFWBBPGATxeRxhQ_9N5VhHi7STWPFD5HIJyVqz436bbVvM6Py_oldT_xt_tWlPc0w4Pesy2CgaCPlJCnx6cjEg_sRBUcRkBoHqa7aZj4JFFm9bzEaiJ2MKfkHVT4xdbEimMHsD0HkIQpg5-zoB2Jsqgc6Qi3L57hZi-Q1V0G2lmdZ5WZkQ2m5hxle4hHtAmghgynK2p0qzDWHScxHcdd2sInYqQgMYbnvs04YYKWpIfndCUBs9q_EONN5tn8gfSwHEKlQ-KpplEL5kc-99h2uaZsxRlJOF6_z8EZ-aKaKY8jvoAV0g4kZJH5UKy_MkBiva6r-zXUmo88qJjXQatOOSdfvJUTiZiSfcpBQqF9SSDD9WWsgInaOCKO_fAFf9fuacXDMEj0esUx1YrVEe_77S5uObg-UrK405U1JhKJJvd7o8xQKxenv5BJdsbbyYQDbSSe9BrCqeHEgmfRHTXdSvl_3QOP0Ej-dT8YJJHZ1lrujU7Zg5f5Kg99tU5GdLMbHX2kt4F2a0NX09HikEemvUg4NLPhjOihfVkChr-zdF69nfsnTiaQrMgpIcl9jttN99_8Gju-LU8OWbb92m9RLxAUFP115v22f77YPoILm92IjMZMkxEhGneoclWhnudkyR7YoTBjCnT5b7AC9_05uls637FmVf7Ck8-MF4gLil3dstXi4g24bitYhxxqWwiqF4vsDouSGUnuKCMwx3TLsII_xk77TjpQP4vpLdYM3tn94AVlTMMhnI-OZkVJk-_mIbywCwRHlQb5nzVCc0BWlM1kb9PJys2IfciS8LWEoxeq9moDX5w72yJKoLN3CWpD3VdJAiW79zUaySw-IeW0XaHnlze5fYnOozG8lIeyQ9sMZasMiFovGnR3b7jyMtA38U33v16fouWuBILOu0m_QOpRDI9i3rjRM6hdC48zCtNSzc1_1VPYkWDSFK1oVAjdd8-2rjyqdPeUwnqD26VA9_d3R7x8ThrazdbRC8U1hr9jpqNHuZ4LGYu3Ui8wB-lSt9QMaHz517MY_zBEoNGyvbQWtlM7mvLu12KoMM7nvGrPJnvD-HmxTqsVQolD8_lIV5ao72yiKDpArVr6RuV4PpI0j_Wy4-yDCuwBW0gjnB9GvCwOTeByYXJT6Ul7dgHck4BbF3IyFgvmY--ceWr5mBrbAC9LJP_4Wf5O6ul3hFrhiG6zSV4zzBYLnEwfW6LNLEZjZKgmBYiC5s1xlxYWDdcQ5FGmLQ9uEDkr4VItXQWvIIdeBQPyujxmd965Mig9-Sa7SCyV_3wH8fQnGlvU-jJMGL0zvzB2gcu7hMLMagUBj1AKXj-UxpbX1i95f2TOiZDwMeCCszgvCjQ21XKg07TBXrrOiFcgcADgdo-HJr7O1T3ozOIulq1PDM7QZH6i3wDD0j3b0NCdqKCWqhfLXz2-FszyUHmA_GCzOLVzrLT2DcGWIcQbkvF0yZPgTyqKArKa8qytOerdH6oCJ0bRl96855sMVjuUdyVLX7XW_rVTwsOwV0gVAx8SrzovtDFeHRNl7BQKMsyQ1BjWu25jqKJ598vAi3LCZv0kMdiC24qPdgZU4e2aUkco11EnD6nJgdqsVFxufCl4BD_D9g5Wy42fJt4ZgNPAcbUf341KERyReeBEQj-qlPB3IUTIXcJw68GScebhxb0W_tGKMBC6-ip4QfNW7UTxUxVxmCV7h0yRnBBlkuUR1eYQwWRmEPjKd3dLHvgHtr266NQmE1tnKtJlsdPKb0ztrI9vogsENsgGNFQ2tHoeX8vqxcagGznlPVPfc3DlqjBSeTFQaPWvmCQHVKgxkbvffKzFQyFvXEqt6bGGtkwBoRJ_IIwtSeWQ2nFPBe3rlyKrtSnQFIMibJbbYvPVE03Cld9R61r-GGDSQz4aXekLzePEVwnxpe4mWJGco7ctQyE73PekL1uo2g0bRK-KgaE878OiLRBo5T7c633xEf2hMy9532M2GVdTZuoE0LL-wpAh9GmNdvJZc7g2sINvwZi778v2WHcYEKqXvdmrX-Shyh3QkzgIGZrDzM4UlxxUWaXfZ0Z6PNguk7Jafqf3xuUe9Z8zfAJl5c_VA3k8dn7IRg99hRsh-TGBCzqzgjJq4p4XMWP2QuxFTGSgHRe2GSCFzd5-lPjrj76ZyT3MPUxQe_bV2VE-Oys3MT-VkCCM8jFCANXdrfltG6jSiUZ2uJUWNqdNnxPglmmyrgff_m-5CyIRWYXQsIdZGspqdjzb4F6RbBKfL2PQlM6zUfo9JNmE8YQq815Nxkex8vDOrImnew312fZA6rRjr9_uE4lEbw3U7PFlCKBUPvPnsdgedjKYhiS0xU6iS1NDKOvYhcrkCkiU67EmFD4U0-OCv9Kpbb5bIxTJuv405NxJBElAMVI-ya0ns7D4-xUPn05E7PhtGZT0eHwItjT6omThTsTHwB_bQqYfNrjrObO1l1go2hQ-cUadZYsG5l47CB5RlFhANtaC8tiq4KJi48TmEEApB_0VwOI4EmI7SR0oaqx3HRXZfeGevCx2yC9aCYM4HqcyqP2g_1HwsOYzwq4XDEbK5Yl1dtYABxPoo7t8FBq2sSmfrBJWFv_nvreb_DPwbfoSeCy9knqvOktSQRrPMmo-nNGpandBvjmrjSk3EdeziAP7XNre5I-bn_2voDxkzGFtUM-wzlL379ASRGej8FkNWaOyqGP6Anq5PSJ',\n      priv: 'LZSOlEPbU9S5_mSsMULffTyxZu6qKEOQ1nfEi2NCscg',\n    },\n    pkcs8: `-----BEGIN PRIVATE KEY-----\nMDQCAQAwCwYJYIZIAWUDBAMTBCKAIC2UjpRD21PUuf5krDFC3308sWbuqihDkNZ3\nxItjQrHI\n-----END PRIVATE KEY-----`,\n    spki: `-----BEGIN PUBLIC KEY-----\nMIIKMjALBglghkgBZQMEAxMDggohAA2V6mgQE0TdBkbYoMc5C8aewvXxWMSOxpfr\nXX16iR281Qk070X0cGXLt2JqbFGFwXV9qVbEOdUJasTLJSgUZnzQmpwS3H3ee6qB\nCG9CuhiCmRh8ZbK/WlzYxBnCjKNCAqJ9C2E701q5e9js/tshAP2mzyt/3QVBRgGE\nOpDkIQB3E9QjJk03JNtz5xHeVlKWH2TgPYIhV/XTVa63RVnM4/7wzrcvNTmzSrMX\n1Vk9Zxu3OtFAicW9nNrTKwcd66ex33P2joOeFuSh6HCYtBGotKJOG7skk3tFAkgl\nE5HqAnHYgAYDhQYl0WM6Zty8+LqLeoUoBaboeu3xPWaYLZ+uL3yPjtZoHD6zz6Xd\n8gPdia6vnb17jOecNUZgP4YWt1OUodr5tLQ9VOe6veOVKaRUXiL//DQCgZMUP7x4\npe8kpvpuyADPrE1GPOvyKjGaorMaM+xX+2UdryIlJt/i9KMOAfLj7Ar9mZVKFV7z\nBel0Ijh7IKoD9a3x/A5n5jxbncIl6wFusBJotdLJD5pDfdmgt0zxup5mja8kO3/C\nfNslZhsVvVO8zG4NtajZERgYv9WMBLeg/FdqVFr+VNWuKePjGtH+LkBuINKHTPlh\nqJpYe6WVmX97H34j15PcAaxorMbQibmgeb7ZIXlsaRH1qp4XN0HTln67EYOj9Yez\nPeUjVVtFPAN/MMK6jzqcxJ3JAlXQq2c9m9ilZZ+muLcHyDYNft5RGUeK5BJk2k2J\nSxZV820RVgQTxgE8XkcYUP/TeVYR4u0k1jxQ+RyCclas+N+m21bzOj8v6JXU/8bf\n7VpT3NMOD3rMtgoGgj5SQp8enIxIP7EQVHEZAaB6mu2mY+CRRZvW8xGoidjCn5B1\nU+MXWxIpjB7A9B5CEKYOfs6AdibKoHOkIty+e4WYvkNVdBtpZnWeVmZENpuYcZXu\nIR7QJoIYMpytqdKsw1h0nMR3HXdrCJ2KkIDGG577NOGGClqSH53QlAbPavxDjTeb\nZ/IH0sBxCpUPiqaZRC+ZHPvfYdrmmbMUZSThev8/BGfmimimPI76AFdIOJGSR+VC\nsvzJAYr2uq/s11JqPPKiY10GrTjknX7yVE4mYkn3KQUKhfUkgw/VlrICJ2jgijv3\nwBX/X7mnFwzBI9HrFMdWK1RHv++0ubjm4PlKyuNOVNSYSiSb3e6PMUCsXp7+QSXb\nG28mEA20knvQawqnhxIJn0R013Ur5f90Dj9BI/nU/GCSR2dZa7o1O2YOX+SoPfbV\nORnSzGx19pLeBdmtDV9PR4pBHpr1IODSz4YzooX1ZAoa/s3RevZ37J04mkKzIKSH\nJfY7bTfff/Bo7vi1PDlm2/dpvUS8QFBT9deb9tn++2D6CC5vdiIzGTJMRIRp3qHJ\nVoZ7nZMke2KEwYwp0+W+wAvf9ObpbOt+xZlX+wpPPjBeIC4pd3bLV4uINuG4rWIc\ncalsIqheL7A6LkhlJ7igjMMd0y7CCP8ZO+046UD+L6S3WDN7Z/eAFZUzDIZyPjmZ\nFSZPv5iG8sAsER5UG+Z81QnNAVpTNZG/TycrNiH3IkvC1hKMXqvZqA1+cO9siSqC\nzdwlqQ91XSQIlu/c1GsksPiHltF2h55c3uX2JzqMxvJSHskPbDGWrDIhaLxp0d2+\n48jLQN/FN979en6LlrgSCzrtJv0DqUQyPYt640TOoXQuPMwrTUs3Nf9VT2JFg0hS\ntaFQI3XfPtq48qnT3lMJ6g9ulQPf3d0e8fE4a2s3W0QvFNYa/Y6ajR7meCxmLt1I\nvMAfpUrfUDGh8+dezGP8wRKDRsr20FrZTO5ry7tdiqDDO57xqzyZ7w/h5sU6rFUK\nJQ/P5SFeWqO9soig6QK1a+kbleD6SNI/1suPsgwrsAVtII5wfRrwsDk3gcmFyU+l\nJe3YB3JOAWxdyMhYL5mPvnHlq+Zga2wAvSyT/+Fn+Turpd4Ra4Yhus0leM8wWC5x\nMH1uizSxGY2SoJgWIgubNcZcWFg3XEORRpi0PbhA5K+FSLV0FryCHXgUD8ro8Znf\neuTIoPfkmu0gslf98B/H0Jxpb1PoyTBi9M78wdoHLu4TCzGoFAY9QCl4/lMaW19Y\nveX9kzomQ8DHggrM4Lwo0NtVyoNO0wV66zohXIHAA4HaPhya+ztU96MziLpatTwz\nO0GR+ot8Aw9I929DQnaiglqoXy189vhbM8lB5gPxgszi1c6y09g3BliHEG5LxdMm\nT4E8qigKymvKsrTnq3R+qAidG0ZfevOebDFY7lHclS1+11v61U8LDsFdIFQMfEq8\n6L7QxXh0TZewUCjLMkNQY1rtuY6iieffLwItywmb9JDHYgtuKj3YGVOHtmlJHKNd\nRJw+pyYHarFRcbnwpeAQ/w/YOVsuNnybeGYDTwHG1H9+NShEckXngREI/qpTwdyF\nEyF3CcOvBknHm4cW9Fv7RijAQuvoqeEHzVu1E8VMVcZgle4dMkZwQZZLlEdXmEMF\nkZhD4ynd3Sx74B7a9uujUJhNbZyrSZbHTym9M7ayPb6ILBDbIBjRUNrR6Hl/L6sX\nGoBs55T1T33Nw5aowUnkxUGj1r5gkB1SoMZG733ysxUMhb1xKremxhrZMAaESfyC\nMLUnlkNpxTwXt65ciq7Up0BSDImyW22Lz1RNNwpXfUeta/hhg0kM+Gl3pC83jxFc\nJ8aXuJliRnKO3LUMhO9z3pC9bqNoNG0SvioGhPO/Doi0QaOU+3Ot98RH9oTMved9\njNhlXU2bqBNCy/sKQIfRpjXbyWXO4NrCDb8GYu+/L9lh3GBCql73Zq1/kocod0JM\n4CBmaw8zOFJccVFml32dGejzYLpOyWn6n98blHvWfM3wCZeXP1QN5PHZ+yEYPfYU\nbIfkxgQs6s4IyauKeFzFj9kLsRUxkoB0Xthkghc3efpT464++mck9zD1MUHv21dl\nRPjsrNzE/lZAgjPIxQgDV3a35bRuo0olGdriVFjanTZ8T4JZpsq4H3/5vuQsiEVm\nF0LCHWRrKanY82+BekWwSny9j0JTOs1H6PSTZhPGEKvNeTcZHsfLwzqyJp3sN9dn\n2QOq0Y6/f7hOJRG8N1OzxZQigVD7z57HYHnYymIYktMVOoktTQyjr2IXK5ApIlOu\nxJhQ+FNPjgr/SqW2+WyMUybr+NOTcSQRJQDFSPsmtJ7Ow+PsVD59OROz4bRmU9Hh\n8CLY0+qJk4U7Ex8Af20KmHza46zmztZdYKNoUPnFGnWWLBuZeOwgeUZRYQDbWgvL\nYquCiYuPE5hBAKQf9FcDiOBJiO0kdKGqsdx0V2X3hnrwsdsgvWgmDOB6nMqj9oP9\nR8LDmM8KuFwxGyuWJdXbWAAcT6KO7fBQatrEpn6wSVhb/5763m/wz8G36EngsvZJ\n6rzpLUkEazzJqPpzRqWp3Qb45q40pNxHXs4gD+1za3uSPm5/9r6A8ZMxhbVDPsM5\nS9+/QEkRno/BZDVmjsqhj+gJ6uT0iQ==\n-----END PUBLIC KEY-----`,\n  },\n}\n"
  },
  {
    "path": "tap/generate_options.ts",
    "content": "import type QUnit from 'qunit'\nimport type * as jose from '../src/index.js'\n\nexport default async (\n  QUnit: QUnit,\n  lib: typeof jose,\n  _lib: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n) => {\n  const { module, test } = QUnit\n  module('generate_options.ts')\n\n  for (const extractable of [undefined, true, false]) {\n    test(`secret CryptoKey extractable: ${extractable ?? 'default (false)'}`, async (t) => {\n      const expected = extractable ?? false\n      const secret = (await lib.generateSecret('HS256', { extractable })) as CryptoKey\n      t.equal(secret.extractable, expected)\n    })\n  }\n\n  for (const extractable of [undefined, true, false]) {\n    test(`CryptoKeyPair extractable: ${extractable ?? 'default (false)'}`, async (t) => {\n      const expected = extractable ?? false\n      const kp = await lib.generateKeyPair('ES256', { extractable })\n      t.equal(kp.privateKey.extractable, expected)\n      t.equal(kp.publicKey.extractable, true)\n    })\n  }\n\n  for (const modulusLength of [undefined, 2048, 3072]) {\n    test(`RSA modulusLength ${modulusLength ?? 'default (2048)'}`, async (t) => {\n      const expected = modulusLength ?? 2048\n      const { publicKey } = (await lib.generateKeyPair('RS256', {\n        modulusLength,\n      })) as CryptoKeyPair\n\n      t.equal((publicKey.algorithm as RsaHashedKeyAlgorithm).modulusLength, expected)\n    })\n  }\n}\n"
  },
  {
    "path": "tap/hmac.ts",
    "content": "import type QUnit from 'qunit'\nimport type * as jose from '../src/index.js'\nimport * as roundtrip from './sign.js'\n\nexport default (\n  QUnit: QUnit,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n) => {\n  const { module, test } = QUnit\n  module('hmac.ts')\n\n  const algorithms = ['HS256', 'HS384', 'HS512']\n\n  function digestSizeSecretsFor(alg: string) {\n    return [\n      keys.generateSecret(alg, { extractable: true }),\n      crypto.getRandomValues(new Uint8Array(parseInt(alg.slice(2, 5), 10) >> 3)),\n    ]\n  }\n\n  function nonDigestSizeSecretFor(alg: string) {\n    const length = parseInt(alg.slice(2, 5), 10) >> 3\n    return [\n      crypto.getRandomValues(new Uint8Array(length - 1)),\n      crypto.getRandomValues(new Uint8Array(length + 1)),\n    ]\n  }\n\n  for (const alg of algorithms) {\n    test(alg, async (t) => {\n      for await (const secret of digestSizeSecretsFor(alg)) {\n        await roundtrip.jws(t, lib, keys, alg, secret)\n      }\n    })\n\n    test(`${alg} w/ non-digest output length secrets`, async (t) => {\n      for await (const secret of nonDigestSizeSecretFor(alg)) {\n        await roundtrip.jws(t, lib, keys, alg, secret)\n      }\n    })\n\n    test(`${alg} JWT`, async (t) => {\n      await roundtrip.jwt(t, lib, keys, alg, await digestSizeSecretsFor(alg)[0])\n    })\n  }\n}\n"
  },
  {
    "path": "tap/jwk.ts",
    "content": "import type QUnit from 'qunit'\nimport * as env from './env.js'\nimport { KEYS } from './fixtures.js'\nimport type * as jose from '../src/index.js'\n\nexport default (\n  QUnit: QUnit,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n) => {\n  const { module, test } = QUnit\n  module('jwk.ts')\n\n  type Vector = [string, JsonWebKey]\n\n  const algorithms: Vector[] = [\n    ['ECDH-ES', KEYS.P256.jwk],\n    ['ECDH-ES', KEYS.P384.jwk],\n    ['ECDH-ES', KEYS.P521.jwk],\n    ['ECDH-ES', KEYS.X25519.jwk],\n    ['Ed25519', KEYS.Ed25519.jwk],\n    ['EdDSA', KEYS.Ed25519.jwk],\n    ['ES256', KEYS.P256.jwk],\n    ['ES384', KEYS.P384.jwk],\n    ['ES512', KEYS.P521.jwk],\n    ['PS256', KEYS.RSA.jwk],\n    ['PS384', KEYS.RSA.jwk],\n    ['PS512', KEYS.RSA.jwk],\n    ['RS256', KEYS.RSA.jwk],\n    ['RS384', KEYS.RSA.jwk],\n    ['RS512', KEYS.RSA.jwk],\n    ['RSA-OAEP-256', KEYS.RSA.jwk],\n    ['RSA-OAEP-384', KEYS.RSA.jwk],\n    ['RSA-OAEP-512', KEYS.RSA.jwk],\n    ['RSA-OAEP', KEYS.RSA.jwk],\n    ['ML-DSA-44', KEYS['ML-DSA-44'].jwk],\n    ['ML-DSA-65', KEYS['ML-DSA-65'].jwk],\n    ['ML-DSA-87', KEYS['ML-DSA-87'].jwk],\n  ]\n\n  function publicJwk(jwk: JsonWebKey) {\n    const { d, p, q, dp, dq, qi, k, priv, ...result } = jwk\n    return result\n  }\n\n  for (const vector of algorithms.slice()) {\n    algorithms.push([vector[0], publicJwk(vector[1])])\n  }\n\n  function title(alg: string, jwk: JsonWebKey, supported = true) {\n    let result = ''\n    if (!supported) {\n      result = '[not supported] '\n    }\n    result += `${alg} `\n    if (alg === 'EdDSA' || alg === 'ECDH-ES') {\n      result += `${jwk.crv} `\n    }\n    result += jwk.d || jwk.priv ? 'Private' : 'Public'\n    result += ' JWK Import'\n    return result\n  }\n\n  for (const vector of algorithms) {\n    const [alg, jwk] = vector\n\n    const execute = async (t: typeof QUnit.assert) => {\n      const key = await lib.importJWK({ ...jwk, ext: true } as jose.JWK, alg)\n\n      const exported = await lib.exportJWK(key)\n\n      for (const prop of [...new Set([...Object.keys(jwk), ...Object.keys(exported)])]) {\n        t.strictEqual(\n          exported[prop as keyof JsonWebKey],\n          jwk[prop as keyof JsonWebKey],\n          `${prop} mismatch`,\n        )\n      }\n\n      if (env.isNode && lib.importJWK !== keys.importJWK) {\n        const nCrypto = globalThis.process.getBuiltinModule('node:crypto')\n        t.deepEqual(\n          await lib.exportJWK(\n            nCrypto[jwk.d || jwk.priv ? 'createPrivateKey' : 'createPublicKey']({\n              format: 'jwk',\n              key: jwk,\n            }),\n          ),\n          exported,\n        )\n      }\n\n      t.ok(1)\n    }\n\n    const op = `${jwk.d || jwk.priv ? 'private' : 'public'} jwk import`\n    if (env.supported(alg, op) && env.supported(jwk.crv, op)) {\n      test(title(alg, jwk), execute)\n    } else {\n      test(title(alg, jwk, false), async (t) => {\n        await t.rejects(execute(t))\n      })\n    }\n  }\n}\n"
  },
  {
    "path": "tap/jwks.ts",
    "content": "import type QUnit from 'qunit'\nimport type * as jose from '../src/index.js'\n\nexport default (QUnit: QUnit, lib: typeof jose) => {\n  const { module, test } = QUnit\n  module('jwks.ts')\n\n  const jwksUri = 'https://www.googleapis.com/oauth2/v3/certs'\n\n  test('[createRemoteJWKSet] fetches the JWKSet', async (t: typeof QUnit.assert) => {\n    const response = await fetch(jwksUri).then((r) => r.json())\n    const { alg, kid } = response.keys[0]\n\n    const jwks = lib.createRemoteJWKSet(new URL(jwksUri))\n    t.false(jwks.coolingDown)\n    t.false(jwks.fresh)\n    t.equal(jwks.jwks(), undefined)\n\n    await t.rejects(jwks({ alg: 'RS256' }), 'multiple matching keys found in the JSON Web Key Set')\n    await t.rejects(\n      jwks({ kid: 'foo', alg: 'RS256' }),\n      'no applicable key found in the JSON Web Key Set',\n    )\n    t.ok(await Promise.all([jwks({ alg, kid }), jwks({ alg, kid })]))\n\n    t.true(jwks.coolingDown)\n    t.true(jwks.fresh)\n    t.ok(jwks.jwks())\n  })\n\n  test('[createLocalJWKSet] establishes local JWKSet', async (t: typeof QUnit.assert) => {\n    const keys = [\n      {\n        e: 'AQAB',\n        n: 'wAR7gpvDJx2cUR15R1gyBYxEXanhOIDzk7evzadBpNCEpf6HA6utqMrf8dZ3EXSslKPSPBD5Qrz63kc2u8y7NqzwJQIi_i5xR6AxAyWLG3_kOHBwxnct6talLCZqgr8pDwnyP1BPnIaNf2hZxgS-UZbHCAVycd1n2qCdyb4FzFhcaNtiOLg5VSfgvtOdhHQlDXW-DBvwatpd9HzzTP6l5MZRyQ-N_AoGbIfhNCZRUfnb-A8IBPSqXBWN4TEpt-0yHAOIhWnSpu66AYE4f1efZdHVFCTQZ13e5bS-5RQra4pfmGqU9hog1j1SpHnDTia-s__qGi43rev2MqzY-qeUlw',\n        d: 'buWn14TSLtMhJo_ZLWU4bo_WJCoq0xFWm-eodyOz-9YZ5iycGXibcTLKJ8fvOHuj-KysjNhYvTybvqhuagQR08AJabZUM2zrK6zO4bxbHOS-EAKQf27xbAHPnzIIrb5tnivmZr6hXAsxyXWg84ZlzIVCKdXLhQuUIWZF-u_uNVeJSUTDMRVTL2J0mzAGTXqi-yHejapEeLS7lFXDe6cpDnBVXauJfB4GmSUOjxtdAEVW7uGNQJGarGwRz6l3Tpy_xQiYl8e_IrU1N6qAN_HJEBrdgfK7js93RcsxHGbtdnj1ylevZqGFpB1UXrWE4JSz3sJgyXrmKNFFWOCjalMccQ',\n        p: '98OCXxur1omXdjfWkDubqkI3xRehVQryIhqt0go-1yLS4Nwa7KyrdAbzTo81bCHN0A-NlmIvHA4YZc8QUHftq65s4nCbb3g_CwTfGCJEVCvoaTO2EE6Pd8VrGu2PVsN4SM52Gc0TNJGS54yUhyCWDTi1onUBEg8gnqpMSoWuaVM',\n        q: 'xmaRdSJf4wN5Vse5jiIjZy5jy9veHHhzXxTmW25epr9KTMERUDDCzX0bNbnF8jCvDFN5ebzcEe-9nkWyzJ17wVcJTouEfw8A5pBPcx6Gr8Kd8WIrUjuom4xu-4619kMItoV4j62_nq3p0QUGot_6CgUdq63PCp9Fh-sHv8wViy0',\n        dp: '0OCXwbzfYu_-rCCpGFHYi3Jl-BhS4BJpTc02K3SNw-vM4ttNK6jqptfRObLMNAxPqg_iqxy9YKaVdQdbVqu0yF811rVepVw3sf96YatJ9bhKqJ566EaC91ONV1dd16TVfHPq5xeYEGKF-gXvlfgn6J-dqYeAzovIUVt7E_ydrJc',\n        dq: 'sYDOnqe0dhyDkNp77ugoGIZujtMVcw9o2SaPujmSwUjfprANV1tozgQiNf0RVk-sLTD5u6r2ka2WTmY5Q8uaDy5Zi0ZTsoGv4pg2HN6wzcsnF_EmpRnvDcuk97eEoOD0iKf9Zz6h88vRJ0qB13Lf99r_4rtMQ0qgIKxscHKcy7k',\n        qi: '7uvpgL15VFjd_zjhU0fPVeTzAa6Vg3P3Q2v5DLwLkAIlQDqF50maTYztxtxssVNJtEMIxKefwrmGkyVCXNhrGHZDoj7wj-2o0k878bQqtltCO2TPm9TSYZgW7dR3ji0t4Msc5DcrQL002M_Vxqr9MAunQcAsnulRTepQM2n-aOc',\n        kty: 'RSA',\n        kid: 'ZuLUAgyr6RQV3ERjDukHzOO_90rVbrPiE1vD_HtPFuM',\n      },\n      {\n        e: 'AQAB',\n        n: '0PjQVV2ZAT27Y0h7hfAWWcnPetORCvR1_gHvEUxtlrlnhZia7utHl7BCJH9HP17YHMMBeeEkmUDflYoUL6MDl4DYHgVDq8jZfu1pxH1XqrpeswqOVoReknEe0F5kRt_mPtIoShI2Qv-pxGAw392akAXTirVRLL4Fn_0Oiifxp182P7eTPy41rlKDevLHuKHBZzzaes_33YE2epY2YCLp9k3mZ-tJEei2qiq0T1fERQicGUL8kppOnz0cDNuKRBHyYtXWhjhuDQ8OZQHNLfte9cqzTJMJ4Leu4MGjikSZMsk-_aRFnXtYHH0orwY-giSenRnwNaReAXaR1Px9ReljAQ',\n        d: 'LXGufKH6IBb4pUKh-iKX-ba1dBSGOkenUTHCd5STUG_JX3gsWUC5NPeTqrQzHkjV3otZytN3TgyZkr-QXDurEEtotD6Y1Ma85aljkuNfKTWWWoE1KwNmPZp0BQRB8lfGjmrNcC49tpw6owX4GvbqId_ifQupN32rY3t4qfq9xpO9SAqZF0oUMoS7xE0zChsCJmNYpD9jx87p5Vud1naeaZPlvwWW0ITV4kp2zjYSbBh5DkI52rSrGjkuzlsJ_lKJk5YB557OHhN9XTRBnjqlwwWevh6QAoUivqpcelcplgmfxTHoII1opovYXn8AVt-DbGSO_7LLJ0Sw9sJR5GAqcQ',\n        p: '9RdDqZ3O73lH6nWUGi0abQRRfgvj-HM0zP7GSDQ185l-ZByletl1VuJ86qYJTUY8Q3Gagv6_eXmQMo_14-0wT_FPUMiTMYsjw5QNgFgjlJTM1AayS_U5ddix_Ut7Kti7EXgM0gsavsIazv2-xwCrFzD4sa-t2FWELzzWxgt8wbs',\n        q: '2kX8MN8ItGnn7NnPx-0iqe8kkhy5s9gJRiD3mxN9E6xzRCnf488yhc3aBwI9kZzQtV0XVjX5VhCws5vnJv9b7KA8NATDhpGNrqy2h9ncmsjTTjafUg3jb6QG08kIKDR-A97Mc-MJbIUNzYs10BAG4z9wk7t1bdo4gZJEvjiXVHM',\n        dp: 'Ahggy-I9Um6G3soCafbYsvXGfH09hXH2kYnbx-IqU9qL6e8UuugAyK1Gw_qHOdHP0gO2fkgO-sq_IK96OmhccVJuixIrr9CwjYtGUkJui2Z6GZW1EFEYHJmta6ypcMRJVOzhrynJILgn4nzolGq9C4WvmlUV9zND3eN3MloGxuE',\n        dq: 'uXKWlusX2TjVvM0-FO2r8tdkqeNP_7XAA15FIPOI5Cszb6loOIQ0t6wy3puPteSXClBCYJPQ-MeLab4-wUpaTovBOq0FdpK53ruNBZUbMkMIDL6p1CxKnPKufkeh747RtfYYnSk7O4E8PfNV0CWdxHuE6W9ukNvEAIpGb5tjL3M',\n        qi: '3BLQ03cHEmO8nUT7U8M_H_JciEWAH8XWh_9nihIhXzLKYbNmWM16Ah0F9DUg0GPeiG7e_08ZJ4X3oK1bHnnXdns6NSOEoULWfHl5LUY5PoFPYaBDy3f6td2SCTE83p1YzegXKysWEk1snA2ROq4UEfz1vL8v64RtwR3SvNrAyOI',\n        kty: 'RSA',\n        alg: 'RS256',\n        kid: 'hJU8GvYjtifxLVuBDSNmhLBF19wQHaZvQhfpT3wKzpE',\n      },\n      {\n        crv: 'P-256',\n        x: 'fqCXPnWs3sSfwztvwYU9SthmRdoT4WCXxS8eD8icF6U',\n        y: 'nP6GIc42c61hoKqPcZqkvzhzIJkBV3Jw3g8sGG7UeP8',\n        d: 'XikZvoy8ayRpOnuz7ont2DkgMxp_kmmg1EKcuIJWX_E',\n        kty: 'EC',\n        kid: 'a-5xuiQoRqlLBtec9jRpXoGTVOP10SGnj2Und0CHHxw',\n      },\n    ]\n    const jwks = {\n      keys: [\n        {\n          e: 'AQAB',\n          n: 'wAR7gpvDJx2cUR15R1gyBYxEXanhOIDzk7evzadBpNCEpf6HA6utqMrf8dZ3EXSslKPSPBD5Qrz63kc2u8y7NqzwJQIi_i5xR6AxAyWLG3_kOHBwxnct6talLCZqgr8pDwnyP1BPnIaNf2hZxgS-UZbHCAVycd1n2qCdyb4FzFhcaNtiOLg5VSfgvtOdhHQlDXW-DBvwatpd9HzzTP6l5MZRyQ-N_AoGbIfhNCZRUfnb-A8IBPSqXBWN4TEpt-0yHAOIhWnSpu66AYE4f1efZdHVFCTQZ13e5bS-5RQra4pfmGqU9hog1j1SpHnDTia-s__qGi43rev2MqzY-qeUlw',\n          kty: 'RSA',\n          kid: 'ZuLUAgyr6RQV3ERjDukHzOO_90rVbrPiE1vD_HtPFuM',\n        },\n        {\n          e: 'AQAB',\n          n: '0PjQVV2ZAT27Y0h7hfAWWcnPetORCvR1_gHvEUxtlrlnhZia7utHl7BCJH9HP17YHMMBeeEkmUDflYoUL6MDl4DYHgVDq8jZfu1pxH1XqrpeswqOVoReknEe0F5kRt_mPtIoShI2Qv-pxGAw392akAXTirVRLL4Fn_0Oiifxp182P7eTPy41rlKDevLHuKHBZzzaes_33YE2epY2YCLp9k3mZ-tJEei2qiq0T1fERQicGUL8kppOnz0cDNuKRBHyYtXWhjhuDQ8OZQHNLfte9cqzTJMJ4Leu4MGjikSZMsk-_aRFnXtYHH0orwY-giSenRnwNaReAXaR1Px9ReljAQ',\n          alg: 'RS256',\n          kty: 'RSA',\n          kid: 'hJU8GvYjtifxLVuBDSNmhLBF19wQHaZvQhfpT3wKzpE',\n        },\n        {\n          crv: 'P-256',\n          x: 'fqCXPnWs3sSfwztvwYU9SthmRdoT4WCXxS8eD8icF6U',\n          y: 'nP6GIc42c61hoKqPcZqkvzhzIJkBV3Jw3g8sGG7UeP8',\n          kty: 'EC',\n          kid: 'a-5xuiQoRqlLBtec9jRpXoGTVOP10SGnj2Und0CHHxw',\n        },\n        {\n          e: 'AQAB',\n          n: '0PjQVV2ZAT27Y0h7hfAWWcnPetORCvR1_gHvEUxtlrlnhZia7utHl7BCJH9HP17YHMMBeeEkmUDflYoUL6MDl4DYHgVDq8jZfu1pxH1XqrpeswqOVoReknEe0F5kRt_mPtIoShI2Qv-pxGAw392akAXTirVRLL4Fn_0Oiifxp182P7eTPy41rlKDevLHuKHBZzzaes_33YE2epY2YCLp9k3mZ-tJEei2qiq0T1fERQicGUL8kppOnz0cDNuKRBHyYtXWhjhuDQ8OZQHNLfte9cqzTJMJ4Leu4MGjikSZMsk-_aRFnXtYHH0orwY-giSenRnwNaReAXaR1Px9ReljAQ',\n          alg: 'RS256',\n          kty: 'RSA',\n          use: 'enc',\n        },\n        {\n          e: 'AQAB',\n          n: '0PjQVV2ZAT27Y0h7hfAWWcnPetORCvR1_gHvEUxtlrlnhZia7utHl7BCJH9HP17YHMMBeeEkmUDflYoUL6MDl4DYHgVDq8jZfu1pxH1XqrpeswqOVoReknEe0F5kRt_mPtIoShI2Qv-pxGAw392akAXTirVRLL4Fn_0Oiifxp182P7eTPy41rlKDevLHuKHBZzzaes_33YE2epY2YCLp9k3mZ-tJEei2qiq0T1fERQicGUL8kppOnz0cDNuKRBHyYtXWhjhuDQ8OZQHNLfte9cqzTJMJ4Leu4MGjikSZMsk-_aRFnXtYHH0orwY-giSenRnwNaReAXaR1Px9ReljAQ',\n          alg: 'RS256',\n          kty: 'RSA',\n          use: 'sig',\n          key_ops: [],\n        },\n        {\n          // this is not valid\n          e: 'AQAB',\n          kty: 'RSA',\n        },\n      ],\n    }\n\n    const JWKS = lib.createLocalJWKSet(jwks)\n    // Signed JWT\n    {\n      const [jwk] = keys\n      const key = await lib.importJWK({ ...jwk, alg: 'PS256' })\n      const jwt = await new lib.SignJWT()\n        .setProtectedHeader({ alg: 'PS256', kid: jwk.kid })\n        .sign(key)\n      const { key: resolvedKey } = await lib.jwtVerify(jwt, JWKS)\n      t.ok(resolvedKey)\n      t.equal((resolvedKey as jose.KeyLike).type, 'public')\n    }\n    // Compact JWS\n    {\n      const [jwk] = keys\n      const key = await lib.importJWK({ ...jwk, alg: 'PS256' })\n      const jws = await new lib.CompactSign(new Uint8Array(1))\n        .setProtectedHeader({ alg: 'PS256', kid: jwk.kid })\n        .sign(key)\n      const { key: resolvedKey } = await lib.compactVerify(jws, JWKS)\n      t.ok(resolvedKey)\n      t.equal((resolvedKey as jose.KeyLike).type, 'public')\n    }\n    // Flattened JWS\n    {\n      const [jwk] = keys\n      const key = await lib.importJWK({ ...jwk, alg: 'PS256' })\n      const jws = await new lib.FlattenedSign(new Uint8Array(1))\n        .setProtectedHeader({ alg: 'PS256' })\n        .setUnprotectedHeader({ kid: jwk.kid })\n        .sign(key)\n      const { key: resolvedKey } = await lib.flattenedVerify(jws, JWKS)\n      t.ok(resolvedKey)\n      t.equal((resolvedKey as jose.KeyLike).type, 'public')\n    }\n    // General JWS\n    {\n      const [jwk] = keys\n      const key = await lib.importJWK({ ...jwk, alg: 'PS256' })\n      const jws = await new lib.GeneralSign(new Uint8Array(1))\n        .addSignature(key)\n        .setProtectedHeader({ alg: 'PS256' })\n        .setUnprotectedHeader({ kid: jwk.kid })\n        .sign()\n      const { key: resolvedKey } = await lib.generalVerify(jws, JWKS)\n      t.ok(resolvedKey)\n      t.equal((resolvedKey as jose.KeyLike).type, 'public')\n    }\n    {\n      await t.rejects(\n        JWKS({ alg: 'RS256' }),\n        'multiple matching keys found in the JSON Web Key Set',\n      )\n\n      // async iterator (KeyLike)\n      let error = (await JWKS({ alg: 'RS256' }).catch(\n        (err) => err,\n      )) as jose.errors.JWKSMultipleMatchingKeys\n      {\n        const cache = new WeakSet()\n        for await (const ko of error) {\n          t.equal(ko.type, 'public')\n          cache.add(ko)\n        }\n        error = (await JWKS({ alg: 'RS256' }).catch(\n          (err) => err,\n        )) as jose.errors.JWKSMultipleMatchingKeys\n        let i = 0\n        for await (const ko of error) {\n          i++\n          t.true(cache.has(ko))\n        }\n        t.equal(i, 2)\n      }\n    }\n    {\n      const [, { kid }] = keys\n      await t.rejects(\n        JWKS({ alg: 'PS256', kid }),\n        'no applicable key found in the JSON Web Key Set',\n      )\n    }\n    {\n      await JWKS({ alg: 'ES256' })\n    }\n  })\n}\n"
  },
  {
    "path": "tap/jws.ts",
    "content": "import type QUnit from 'qunit'\nimport * as env from './env.js'\nimport type * as jose from '../src/index.js'\nimport * as roundtrip from './sign.js'\n\nexport default (\n  QUnit: QUnit,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n) => {\n  const { module, test } = QUnit\n  module('jws.ts')\n\n  const algorithms = [\n    'Ed25519',\n    'EdDSA',\n    'ES256',\n    'ES384',\n    'ES512',\n    'PS256',\n    'PS384',\n    'PS512',\n    'RS256',\n    'RS384',\n    'RS512',\n    'ML-DSA-44',\n    'ML-DSA-65',\n    'ML-DSA-87',\n  ]\n\n  const kps: Record<string, jose.GenerateKeyPairResult> = {}\n\n  function title(alg: string, supported = true) {\n    let result = ''\n    if (!supported) {\n      result = '[not supported] '\n    }\n    result += `${alg}`\n    return result\n  }\n\n  for (const alg of algorithms) {\n    const execute = async (t: typeof QUnit.assert) => {\n      if (!kps[alg]) {\n        kps[alg] = await keys.generateKeyPair(alg, { extractable: true })\n      }\n      await roundtrip.jws(t, lib, keys, alg, kps[alg])\n    }\n\n    const jwt = async (t: typeof QUnit.assert) => {\n      if (!kps[alg]) {\n        kps[alg] = await keys.generateKeyPair(alg, { extractable: true })\n      }\n      await roundtrip.jwt(t, lib, keys, alg, kps[alg])\n    }\n\n    if (env.supported(alg)) {\n      test(title(alg), execute)\n      test(`${title(alg)} JWT`, jwt)\n    } else {\n      test(title(alg, false), async (t) => {\n        await t.rejects(execute(t))\n      })\n    }\n  }\n}\n"
  },
  {
    "path": "tap/keyobject-stub.ts",
    "content": "/// <reference types=\"node\"/>\n\nimport { promisify } from 'node:util'\nimport * as crypto from 'node:crypto'\nimport { Buffer } from 'node:buffer'\n\nconst generate = promisify(crypto.generateKeyPair)\n\nconst stub: Pick<\n  typeof import('../src/index.js'),\n  'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'\n> = {\n  // @ts-expect-error\n  exportJWK(key) {\n    let k: crypto.KeyObject\n    if (key instanceof Uint8Array) {\n      k = crypto.createSecretKey(key)\n    } else {\n      // @ts-expect-error\n      k = key\n    }\n\n    return (k as unknown as crypto.KeyObject).export({ format: 'jwk' })\n  },\n  // @ts-expect-error\n  importJWK(jwk) {\n    if (jwk.k) {\n      return Buffer.from(jwk.k, 'base64url')\n    }\n    if (jwk.d || jwk.priv) {\n      return crypto.createPrivateKey({ format: 'jwk', key: jwk as crypto.JsonWebKey })\n    }\n    return crypto.createPublicKey({ format: 'jwk', key: jwk as crypto.JsonWebKey })\n  },\n  // @ts-expect-error\n  generateSecret(alg) {\n    let length: number\n    switch (alg) {\n      case 'HS256':\n      case 'HS384':\n      case 'HS512':\n      case 'A128CBC-HS256':\n      case 'A192CBC-HS384':\n      case 'A256CBC-HS512':\n        length = parseInt(alg.slice(-3), 10)\n        break\n      case 'A128KW':\n      case 'A192KW':\n      case 'A256KW':\n      case 'A128GCMKW':\n      case 'A192GCMKW':\n      case 'A256GCMKW':\n      case 'A128GCM':\n      case 'A192GCM':\n      case 'A256GCM':\n        length = parseInt(alg.slice(1, 4), 10)\n        break\n      default:\n        throw new Error('unreachable')\n    }\n\n    return crypto.createSecretKey(crypto.randomBytes(length >> 3))\n  },\n  // @ts-expect-error\n  async generateKeyPair(alg, options) {\n    switch (alg) {\n      case 'RS256':\n      case 'RS384':\n      case 'RS512':\n      case 'PS256':\n      case 'PS384':\n      case 'PS512':\n      case 'RSA-OAEP':\n      case 'RSA-OAEP-256':\n      case 'RSA-OAEP-384':\n      case 'RSA-OAEP-512': {\n        const modulusLength = options?.modulusLength ?? 2048\n        const keypair = await generate('rsa', {\n          modulusLength,\n          publicExponent: 0x10001,\n        })\n        return keypair\n      }\n      case 'ES256':\n        return generate('ec', { namedCurve: 'P-256' })\n      case 'ES384':\n        return generate('ec', { namedCurve: 'P-384' })\n      case 'ES512':\n        return generate('ec', { namedCurve: 'P-521' })\n      case 'Ed25519': // Fall through\n      case 'EdDSA':\n        return generate('ed25519')\n      case 'ECDH-ES':\n      case 'ECDH-ES+A128KW':\n      case 'ECDH-ES+A192KW':\n      case 'ECDH-ES+A256KW': {\n        const crv = options?.crv ?? 'P-256'\n        switch (crv) {\n          case 'P-256':\n          case 'P-384':\n          case 'P-521':\n            return generate('ec', { namedCurve: crv })\n          case 'X25519':\n            return generate('x25519')\n          default:\n            Error('unreachable')\n        }\n      }\n      case 'ML-DSA-44':\n      case 'ML-DSA-65':\n      case 'ML-DSA-87':\n        return generate(alg.toLowerCase())\n      default:\n        Error('unreachable')\n    }\n  },\n}\n\nexport { stub }\n"
  },
  {
    "path": "tap/noop.ts",
    "content": "import type QUnit from 'qunit'\nimport type * as jose from '../src/index.js'\n\n// @ts-ignore\nexport default (QUnit: QUnit, lib: typeof jose) => {}\n"
  },
  {
    "path": "tap/pbes2.ts",
    "content": "import type QUnit from 'qunit'\nimport * as env from './env.js'\nimport type * as jose from '../src/index.js'\nimport * as roundtrip from './encrypt.js'\n\nexport default (\n  QUnit: QUnit,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n) => {\n  const { module, test } = QUnit\n  module('pbes2.ts')\n\n  const algorithms = ['PBES2-HS256+A128KW', 'PBES2-HS384+A192KW', 'PBES2-HS512+A256KW']\n\n  function title(alg: string, supported = true) {\n    let result = ''\n    if (!supported) {\n      result = '[not supported] '\n    }\n    result += `${alg}`\n    return result\n  }\n\n  for (const alg of algorithms) {\n    const execute = async (t: typeof QUnit.assert) => {\n      const password = new TextEncoder().encode('letmein')\n      await roundtrip.jwe(t, lib, keys, alg, 'A128GCM', password)\n    }\n\n    const jwt = async (t: typeof QUnit.assert) => {\n      const password = new TextEncoder().encode('letmein')\n      await roundtrip.jwt(t, lib, keys, alg, 'A128GCM', password)\n    }\n\n    if (env.supported(alg)) {\n      test(title(alg), execute)\n      test(`${title(alg)} JWT`, jwt)\n    } else {\n      test(title(alg, true), async (t) => {\n        await t.rejects(execute(t))\n      })\n    }\n  }\n}\n"
  },
  {
    "path": "tap/pem.ts",
    "content": "import type QUnit from 'qunit'\nimport * as env from './env.js'\nimport { KEYS } from './fixtures.js'\nimport type * as jose from '../src/index.js'\n\nfunction normalize(pem: string) {\n  return pem.replace(/\\s+$/, '')\n}\n\nexport default (\n  QUnit: QUnit,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'importJWK'>,\n) => {\n  const { module, test } = QUnit\n  module('pem.ts')\n\n  type Vector = [string | string[], string]\n  const algorithms: Vector[] = [\n    ['ES256', KEYS.P256.pkcs8],\n    ['ES256', KEYS.P256.spki],\n    ['ES256', KEYS.P256.x509],\n    ['ES384', KEYS.P384.pkcs8],\n    ['ES384', KEYS.P384.spki],\n    ['ES384', KEYS.P384.x509],\n    ['ES512', KEYS.P521.pkcs8],\n    ['ES512', KEYS.P521.spki],\n    ['ES512', KEYS.P521.x509],\n    ['PS256', KEYS.RSA.pkcs8],\n    ['PS256', KEYS.RSA.spki],\n    ['PS256', KEYS.RSA.x509],\n    ['PS384', KEYS.RSA.pkcs8],\n    ['PS384', KEYS.RSA.spki],\n    ['PS384', KEYS.RSA.x509],\n    ['PS512', KEYS.RSA.pkcs8],\n    ['PS512', KEYS.RSA.spki],\n    ['PS512', KEYS.RSA.x509],\n    ['RS256', KEYS.RSA.pkcs8],\n    ['RS256', KEYS.RSA.spki],\n    ['RS256', KEYS.RSA.x509],\n    ['RS384', KEYS.RSA.pkcs8],\n    ['RS384', KEYS.RSA.spki],\n    ['RS384', KEYS.RSA.x509],\n    ['RS512', KEYS.RSA.pkcs8],\n    ['RS512', KEYS.RSA.spki],\n    ['RS512', KEYS.RSA.x509],\n    ['RSA-OAEP-256', KEYS.RSA.pkcs8],\n    ['RSA-OAEP-256', KEYS.RSA.spki],\n    ['RSA-OAEP-256', KEYS.RSA.x509],\n    ['RSA-OAEP-384', KEYS.RSA.pkcs8],\n    ['RSA-OAEP-384', KEYS.RSA.spki],\n    ['RSA-OAEP-384', KEYS.RSA.x509],\n    ['RSA-OAEP-512', KEYS.RSA.pkcs8],\n    ['RSA-OAEP-512', KEYS.RSA.spki],\n    ['RSA-OAEP-512', KEYS.RSA.x509],\n    ['RSA-OAEP', KEYS.RSA.pkcs8],\n    ['RSA-OAEP', KEYS.RSA.spki],\n    ['RSA-OAEP', KEYS.RSA.x509],\n    [['ECDH-ES', 'P-256'], KEYS.P256.pkcs8],\n    [['ECDH-ES', 'P-256'], KEYS.P256.spki],\n    [['ECDH-ES', 'P-256'], KEYS.P256.x509],\n    [['ECDH-ES', 'P-384'], KEYS.P384.pkcs8],\n    [['ECDH-ES', 'P-384'], KEYS.P384.spki],\n    [['ECDH-ES', 'P-384'], KEYS.P384.x509],\n    [['ECDH-ES', 'P-521'], KEYS.P521.pkcs8],\n    [['ECDH-ES', 'P-521'], KEYS.P521.spki],\n    [['ECDH-ES', 'P-521'], KEYS.P521.x509],\n    [['ECDH-ES', 'X25519'], KEYS.X25519.pkcs8],\n    [['ECDH-ES', 'X25519'], KEYS.X25519.spki],\n    ['Ed25519', KEYS.Ed25519.pkcs8],\n    ['Ed25519', KEYS.Ed25519.spki],\n    ['Ed25519', KEYS.Ed25519.x509],\n    [['EdDSA', 'Ed25519'], KEYS.Ed25519.pkcs8],\n    [['EdDSA', 'Ed25519'], KEYS.Ed25519.spki],\n    [['EdDSA', 'Ed25519'], KEYS.Ed25519.x509],\n    ['ML-DSA-44', KEYS['ML-DSA-44'].pkcs8],\n    ['ML-DSA-44', KEYS['ML-DSA-44'].spki],\n    ['ML-DSA-65', KEYS['ML-DSA-65'].pkcs8],\n    ['ML-DSA-65', KEYS['ML-DSA-65'].spki],\n    ['ML-DSA-87', KEYS['ML-DSA-87'].pkcs8],\n    ['ML-DSA-87', KEYS['ML-DSA-87'].spki],\n  ]\n\n  function title(alg: string, crv: string | undefined, pem: string, supported = true) {\n    let result = ''\n    if (!supported) {\n      result = '[not supported] '\n    }\n    result += `${alg} `\n    if (crv) result += `${crv} `\n    result += pem.startsWith('-----BEGIN PRIVATE KEY-----')\n      ? 'PKCS8 Private Key Import'\n      : pem.startsWith('-----BEGIN PUBLIC KEY-----')\n        ? 'SPKI Public Key Import'\n        : 'X.509 Certificate Import'\n    return result\n  }\n\n  for (const vector of algorithms) {\n    const [, pem] = vector\n    let [alg] = vector\n\n    let crv!: string\n    if (Array.isArray(alg)) {\n      ;[alg, crv] = alg\n    }\n\n    let x509 = false\n    let importFn: typeof lib.importSPKI | typeof lib.importPKCS8 | typeof lib.importX509\n    let exportFn: typeof lib.exportSPKI | typeof lib.exportPKCS8\n    switch (true) {\n      case pem.startsWith('-----BEGIN PRIVATE KEY-----'): {\n        importFn = lib.importPKCS8\n        exportFn = lib.exportPKCS8\n        break\n      }\n      case pem.startsWith('-----BEGIN PUBLIC KEY-----'): {\n        importFn = lib.importSPKI\n        exportFn = lib.exportSPKI\n        break\n      }\n      case pem.startsWith('-----BEGIN CERTIFICATE-----'): {\n        importFn = lib.importX509\n        exportFn = lib.exportSPKI\n        x509 = true\n        break\n      }\n      default:\n        throw new Error()\n    }\n\n    const execute = async (t: typeof QUnit.assert) => {\n      const k = await importFn(pem, alg as string, { extractable: true })\n\n      if (!x509) {\n        t.strictEqual(normalize(await exportFn(k)), normalize(pem))\n        if (env.isNode && lib.importJWK !== keys.importJWK) {\n          const nCrypto = globalThis.process.getBuiltinModule('node:crypto')\n          if (pem.startsWith('-----BEGIN PRIVATE KEY-----')) {\n            if (!alg.startsWith('ML-DSA-'))\n              t.strictEqual(\n                normalize(await exportFn(nCrypto.createPrivateKey(pem))),\n                normalize(pem),\n              )\n          } else {\n            t.strictEqual(normalize(await exportFn(nCrypto.createPublicKey(pem))), normalize(pem))\n          }\n        }\n      } else {\n        await exportFn(k)\n      }\n      t.ok(1)\n    }\n\n    if (env.supported(alg, 'pem import') && env.supported(crv, 'pem import')) {\n      test(title(alg, crv, pem), execute)\n    } else {\n      test(title(alg, crv, pem, false), async (t) => {\n        await t.rejects(execute(t))\n      })\n    }\n  }\n}\n"
  },
  {
    "path": "tap/rsaes.ts",
    "content": "import type QUnit from 'qunit'\nimport type * as jose from '../src/index.js'\nimport * as roundtrip from './encrypt.js'\nimport * as env from './env.js'\n\nexport default (\n  QUnit: QUnit,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n) => {\n  const { module, test } = QUnit\n  module('rsaes.ts')\n\n  const kps: Record<string, jose.GenerateKeyPairResult> = {}\n\n  const algorithms = ['RSA-OAEP', 'RSA-OAEP-256', 'RSA-OAEP-384', 'RSA-OAEP-512']\n\n  function title(alg: string, supported = true) {\n    let result = ''\n    if (!supported) {\n      result = '[not supported] '\n    }\n    result += `${alg}`\n    return result\n  }\n\n  for (const alg of algorithms) {\n    const execute = async (t: typeof QUnit.assert) => {\n      if (!kps[alg]) {\n        kps[alg] = await keys.generateKeyPair(alg, { extractable: true })\n      }\n\n      await roundtrip.jwe(t, lib, keys, alg, 'A128GCM', kps[alg])\n    }\n\n    const jwt = async (t: typeof QUnit.assert) => {\n      if (!kps[alg]) {\n        kps[alg] = await keys.generateKeyPair(alg, { extractable: true })\n      }\n\n      await roundtrip.jwt(t, lib, keys, alg, 'A128GCM', kps[alg])\n    }\n\n    if (env.supported(alg)) {\n      test(title(alg), execute)\n      test(`${title(alg)} JWT`, jwt)\n    } else {\n      test(title(alg, false), async (t) => {\n        await t.rejects(execute(t))\n      })\n    }\n  }\n}\n"
  },
  {
    "path": "tap/run-browser.ts",
    "content": "import QUnit from 'qunit'\nimport run from './run.js'\nimport * as lib from '../src/index.js'\n\nrun(QUnit, lib, lib, (stats) => {\n  // @ts-ignore\n  globalThis.stats = stats\n})\n"
  },
  {
    "path": "tap/run-bun.ts",
    "content": "import QUnit from 'qunit'\nimport run from './run.js'\nimport * as lib from '../src/index.js'\n\nconst stats: QUnit.DoneDetails = await new Promise((resolve) => {\n  run(QUnit, lib, lib, resolve)\n})\n\nif (stats?.failed !== 0) {\n  // @ts-ignore\n  process.exit(1)\n}\n"
  },
  {
    "path": "tap/run-deno.ts",
    "content": "import QUnit from 'qunit'\nimport run from './run.js'\nimport * as lib from '../src/index.js'\n\nrun(QUnit, lib, lib, (stats) => {\n  if (stats?.failed !== 0) {\n    // @ts-ignore\n    Deno.exit(1)\n  }\n})\n"
  },
  {
    "path": "tap/run-electron.ts",
    "content": "// @ts-ignore\nimport { app } from 'electron'\nimport QUnit from 'qunit'\nimport run from './run.js'\nimport * as lib from '../src/index.js'\n\napp.on('ready', () => {\n  run(QUnit, lib, lib, (stats) => {\n    if (stats?.failed !== 0) {\n      // @ts-ignore\n      app.exit(1)\n    } else {\n      app.exit(0)\n    }\n  })\n})\n"
  },
  {
    "path": "tap/run-node.ts",
    "content": "/// <reference types=\"node\"/>\n\nimport { parseArgs } from 'node:util'\nimport * as lib from '../src/index.js'\n\nimport QUnit from 'qunit'\n\nimport run from './run.js'\n\nconst {\n  values: { keys },\n} = parseArgs({ options: { keys: { type: 'string' } } })\n\nimport { stub } from './keyobject-stub.js'\n\nconst stats: QUnit.DoneDetails = await new Promise(async (resolve) => {\n  run(QUnit, lib, keys === 'KeyObject' ? stub : lib, resolve)\n})\n\nif (stats?.failed !== 0) {\n  process.exitCode = 1\n}\n"
  },
  {
    "path": "tap/run-workerd.ts",
    "content": "import QUnit from 'qunit'\nimport run from './run.js'\nimport * as lib from '../src/index.js'\n\nexport default {\n  async test() {\n    await new Promise((resolve, reject) => {\n      run(QUnit, lib, lib, (results) => {\n        if (results?.failed !== 0) {\n          reject()\n        } else {\n          // @ts-ignore\n          resolve()\n        }\n      })\n    })\n  },\n}\n"
  },
  {
    "path": "tap/run.ts",
    "content": "import type QUnit from 'qunit'\nimport type * as jose from '../src/index.js'\n\nconst skipFetch =\n  // @ts-ignore\n  typeof fetch === 'undefined' || (typeof process !== 'undefined' && 'CITGM' in process.env)\n\nexport default async (\n  QUnit: QUnit,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n  done: (details: QUnit.DoneDetails) => void,\n) => {\n  // @ts-ignore\n  QUnit.reporters.tap.init(QUnit)\n  QUnit.config.autostart = false\n  QUnit.config.testTimeout = 10_000\n\n  const modules = await Promise.all([\n    !skipFetch ? import('./jwks.js') : import('./noop.js'),\n    import('./aes.js'),\n    import('./aeskw.js'),\n    import('./cookbook.js'),\n    import('./ecdh.js'),\n    import('./generate_options.js'),\n    import('./hmac.js'),\n    import('./jwk.js'),\n    import('./jws.js'),\n    import('./pbes2.js'),\n    import('./pem.js'),\n    import('./rsaes.js'),\n  ])\n  for (const { default: module } of modules) {\n    await module(QUnit, lib, keys)\n  }\n  QUnit.start()\n  QUnit.done(done)\n}\n"
  },
  {
    "path": "tap/sign.ts",
    "content": "import type QUnit from 'qunit'\nimport type * as jose from '../src/index.js'\n\ntype keyType = Uint8Array | jose.CryptoKey | jose.KeyObject | jose.GenerateKeyPairResult\n\nfunction isKeyPair(input: keyType): input is jose.GenerateKeyPairResult {\n  return 'publicKey' in input && 'privateKey' in input\n}\n\nasync function getKeys(\n  secretOrKeyPair: keyType,\n  jwk: false,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n): Promise<Array<Uint8Array | jose.CryptoKey | jose.KeyObject>>\nasync function getKeys(\n  secretOrKeyPair: keyType,\n  jwk: true,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n): Promise<Array<jose.JWK>>\nasync function getKeys(\n  secretOrKeyPair: keyType,\n  jwk: boolean,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n) {\n  let sKey = isKeyPair(secretOrKeyPair) ? secretOrKeyPair.privateKey : secretOrKeyPair\n  let vKey = isKeyPair(secretOrKeyPair) ? secretOrKeyPair.publicKey : secretOrKeyPair\n\n  if (jwk) {\n    // @ts-ignore\n    return [await keys.exportJWK(sKey), await keys.exportJWK(vKey)]\n  }\n\n  return [sKey, vKey]\n}\n\nfunction jwkWithProps(jwk: jose.JWK, alg: string) {\n  jwk = structuredClone(jwk)\n  jwk.alg = alg\n  jwk.use = 'sig'\n  if (jwk.k) {\n    jwk.key_ops = ['sign', 'verify']\n  } else if (jwk.d || jwk.priv) {\n    jwk.key_ops = ['sign']\n  } else {\n    jwk.key_ops = ['verify']\n  }\n\n  return jwk\n}\n\nexport async function jws(\n  t: typeof QUnit.assert,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n  alg: string,\n  secretOrKeyPair: keyType,\n  payload = crypto.getRandomValues(new Uint8Array(16)),\n) {\n  // Test Uint8Array, CryptoKey, and KeyObject key inputs\n  {\n    const [sKey, vKey] = await getKeys(secretOrKeyPair, false, keys)\n    const jws = await new lib.FlattenedSign(payload).setProtectedHeader({ alg }).sign(sKey)\n    {\n      const verified = await lib.flattenedVerify(jws, vKey)\n      t.deepEqual([...verified.payload], [...payload])\n    }\n    {\n      const verified = await lib.flattenedVerify(jws, async () => vKey)\n      t.propContains(verified, {\n        key: vKey,\n        payload,\n        protectedHeader: { alg },\n      })\n    }\n  }\n\n  if (secretOrKeyPair instanceof Uint8Array) return\n\n  // Test JWK key input\n  {\n    const [sKey, vKey] = await getKeys(secretOrKeyPair, true, keys)\n    const jws = await new lib.FlattenedSign(payload).setProtectedHeader({ alg }).sign(sKey)\n    await new lib.FlattenedSign(payload).setProtectedHeader({ alg }).sign(jwkWithProps(sKey, alg))\n    for (const key of [\n      vKey,\n      async () => vKey,\n      jwkWithProps(vKey, alg),\n      async () => jwkWithProps(vKey, alg),\n    ]) {\n      // @ts-ignore\n      const verified = await lib.flattenedVerify(jws, key)\n      t.deepEqual([...verified.payload], [...payload])\n    }\n  }\n\n  // Test JWK key input with all JWK properties\n  {\n    const [sKey, vKey] = await getKeys(secretOrKeyPair, true, keys)\n    const jws = await new lib.FlattenedSign(payload)\n      .setProtectedHeader({ alg })\n      .sign(jwkWithProps(sKey, alg))\n    const verified = await lib.flattenedVerify(jws, {\n      ...vKey,\n      alg,\n      use: 'sig',\n      key_ops: ['verify'],\n    })\n    t.deepEqual([...verified.payload], [...payload])\n  }\n}\n\nexport async function jwt(\n  t: typeof QUnit.assert,\n  lib: typeof jose,\n  keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,\n  alg: string,\n  secretOrKeyPair: keyType,\n) {\n  const [sKey, vKey] = await getKeys(secretOrKeyPair, false, keys)\n  const jwt = await new lib.SignJWT({ foo: 'bar', '🤷‍♂️': '🤷‍♀️' })\n    .setProtectedHeader({ alg, '🤷‍♂️': '🤷‍♀️' })\n    .sign(sKey)\n  const verified = await lib.jwtVerify(jwt, vKey)\n  t.deepEqual(verified, {\n    payload: {\n      foo: 'bar',\n      '🤷‍♂️': '🤷‍♀️',\n    },\n    protectedHeader: {\n      alg,\n      '🤷‍♂️': '🤷‍♀️',\n    },\n  })\n}\n"
  },
  {
    "path": "tap/tsconfig.json",
    "content": "{\n  \"include\": [\"**/*.ts\"],\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n    \"types\": [],\n    \"allowSyntheticDefaultImports\": true,\n    \"strict\": true,\n    \"noEmit\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noImplicitAny\": true\n  }\n}\n"
  },
  {
    "path": "test/jwe/compact.decrypt.test.ts",
    "content": "import test from 'ava'\n\nimport { compactDecrypt } from '../../src/index.js'\n\ntest('JWE format validation', async (t) => {\n  await t.throwsAsync(compactDecrypt(null, new Uint8Array(0)), {\n    message: 'Compact JWE must be a string or Uint8Array',\n    code: 'ERR_JWE_INVALID',\n  })\n  await t.throwsAsync(compactDecrypt('...', new Uint8Array(0)), {\n    message: 'Invalid Compact JWE',\n    code: 'ERR_JWE_INVALID',\n  })\n})\n"
  },
  {
    "path": "test/jwe/compact.encrypt.test.ts",
    "content": "import test from 'ava'\n\nimport { CompactEncrypt } from '../../src/index.js'\n\ntest.before(async (t) => {\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n  t.context.plaintext = encode('It’s a dangerous business, Frodo, going out your door.')\n  t.context.initializationVector = new Uint8Array(12)\n  t.context.secret = new Uint8Array(16)\n})\n\ntest('CompactEncrypt', async (t) => {\n  const jwe = await new CompactEncrypt(t.context.plaintext)\n    .setInitializationVector(t.context.initializationVector)\n    .setProtectedHeader({ alg: 'dir', enc: 'A128GCM' })\n    .encrypt(t.context.secret)\n  t.deepEqual(\n    jwe,\n    'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4R0NNIn0..AAAAAAAAAAAAAAAA.Svw4TvnFg_PTTKPXFteMF4Lmisk8ODBNko7607TNs49EbT0BKRz9tEep2dmks9KPvD-CfX7hW1M.Y5cdeOSFYNyxcPWQlrVFzw',\n  )\n})\n\ntest('CompactEncrypt.prototype.setProtectedHeader', (t) => {\n  t.throws(\n    () => new CompactEncrypt(t.context.plaintext).setProtectedHeader({}).setProtectedHeader({}),\n    {\n      instanceOf: TypeError,\n      message: 'setProtectedHeader can only be called once',\n    },\n  )\n})\n\ntest('CompactEncrypt.prototype.setKeyManagementParameters', (t) => {\n  t.throws(\n    () =>\n      new CompactEncrypt(t.context.plaintext)\n        .setKeyManagementParameters({})\n        .setKeyManagementParameters({}),\n    {\n      instanceOf: TypeError,\n      message: 'setKeyManagementParameters can only be called once',\n    },\n  )\n})\n\ntest('CompactEncrypt.prototype.setInitializationVector', (t) => {\n  t.throws(\n    () =>\n      new CompactEncrypt(t.context.plaintext)\n        .setInitializationVector(t.context.initializationVector)\n        .setInitializationVector(t.context.initializationVector),\n    {\n      instanceOf: TypeError,\n      message: 'setInitializationVector can only be called once',\n    },\n  )\n})\n\ntest('CompactEncrypt.prototype.setContentEncryptionKey', (t) => {\n  t.throws(\n    () =>\n      new CompactEncrypt(t.context.plaintext)\n        .setContentEncryptionKey(t.context.secret)\n        .setContentEncryptionKey(t.context.secret),\n    {\n      instanceOf: TypeError,\n      message: 'setContentEncryptionKey can only be called once',\n    },\n  )\n})\n\ntest('CompactEncrypt.prototype.encrypt must have a JOSE header', async (t) => {\n  await t.throwsAsync(new CompactEncrypt(t.context.plaintext).encrypt(t.context.secret), {\n    code: 'ERR_JWE_INVALID',\n    message:\n      'either setProtectedHeader, setUnprotectedHeader, or sharedUnprotectedHeader must be called before #encrypt()',\n  })\n})\n\ntest('CompactEncrypt.prototype.encrypt JOSE header have an alg', async (t) => {\n  await t.throwsAsync(\n    new CompactEncrypt(t.context.plaintext)\n      .setProtectedHeader({ enc: 'A128GCM' })\n      .encrypt(t.context.secret),\n    {\n      code: 'ERR_JWE_INVALID',\n      message: 'JWE \"alg\" (Algorithm) Header Parameter missing or invalid',\n    },\n  )\n})\n\ntest('CompactEncrypt.prototype.encrypt JOSE header have an enc', async (t) => {\n  await t.throwsAsync(\n    new CompactEncrypt(t.context.plaintext)\n      .setProtectedHeader({ alg: 'dir' })\n      .encrypt(t.context.secret),\n    {\n      code: 'ERR_JWE_INVALID',\n      message: 'JWE \"enc\" (Encryption Algorithm) Header Parameter missing or invalid',\n    },\n  )\n})\n"
  },
  {
    "path": "test/jwe/flattened.decrypt.test.ts",
    "content": "import test from 'ava'\nimport * as crypto from 'crypto'\n\nimport { FlattenedEncrypt, flattenedDecrypt } from '../../src/index.js'\n\ntest.before(async (t) => {\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n  t.context.plaintext = encode('It’s a dangerous business, Frodo, going out your door.')\n  t.context.additionalAuthenticatedData = encode('The Fellowship of the Ring')\n  t.context.initializationVector = new Uint8Array(12)\n  t.context.secret = new Uint8Array(16)\n})\n\ntest('JWE format validation', async (t) => {\n  const fullJwe = await new FlattenedEncrypt(t.context.plaintext)\n    .setProtectedHeader({ bar: 'baz' })\n    .setUnprotectedHeader({ foo: 'bar' })\n    .setSharedUnprotectedHeader({ alg: 'dir', enc: 'A128GCM' })\n    .setAdditionalAuthenticatedData(t.context.additionalAuthenticatedData)\n    .encrypt(t.context.secret)\n\n  await t.notThrowsAsync(flattenedDecrypt(fullJwe, t.context.secret))\n\n  {\n    await t.throwsAsync(flattenedDecrypt(null, t.context.secret), {\n      message: 'Flattened JWE must be an object',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    const jwe = { ...fullJwe }\n    jwe.protected = undefined\n    jwe.header = undefined\n    jwe.unprotected = undefined\n\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), {\n      message: 'JOSE Header missing',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    const jwe = { ...fullJwe }\n    const assertion = {\n      message: 'JWE Initialization Vector incorrect type',\n      code: 'ERR_JWE_INVALID',\n    }\n\n    jwe.iv = 12\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), assertion)\n    jwe.iv = null\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), assertion)\n    jwe.iv = undefined\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), {\n      message: 'JWE Initialization Vector missing',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    const jwe = { ...fullJwe }\n    jwe.ciphertext = undefined\n    const assertion = {\n      message: 'JWE Ciphertext missing or incorrect type',\n      code: 'ERR_JWE_INVALID',\n    }\n\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), assertion)\n    jwe.ciphertext = null\n\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), assertion)\n  }\n\n  {\n    const jwe = { ...fullJwe }\n    const assertion = {\n      message: 'JWE Authentication Tag incorrect type',\n      code: 'ERR_JWE_INVALID',\n    }\n\n    jwe.tag = 12\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), assertion)\n    jwe.tag = null\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), assertion)\n    jwe.tag = undefined\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), {\n      message: 'JWE Authentication Tag missing',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    const jwe = { ...fullJwe }\n    jwe.protected = null\n\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), {\n      message: 'JWE Protected Header incorrect type',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    const jwe = { ...fullJwe }\n    const assertion = {\n      message: 'JWE Protected Header is invalid',\n      code: 'ERR_JWE_INVALID',\n    }\n    jwe.protected = `1${jwe.protected}`\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), assertion)\n  }\n\n  {\n    const jwe = { ...fullJwe }\n    jwe.encrypted_key = null\n\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), {\n      message: 'JWE Encrypted Key incorrect type',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    const jwe = { ...fullJwe }\n    jwe.aad = null\n\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), {\n      message: 'JWE AAD incorrect type',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    const jwe = { ...fullJwe }\n    jwe.header = null\n\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), {\n      message: 'JWE Shared Unprotected Header incorrect type',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    const jwe = { ...fullJwe }\n    jwe.unprotected = null\n\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), {\n      message: 'JWE Per-Recipient Unprotected Header incorrect type',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    const jwe = { ...fullJwe }\n    jwe.unprotected = { foo: 'bar' }\n\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), {\n      message:\n        'JWE Protected, JWE Unprotected Header, and JWE Per-Recipient Unprotected Header Parameter names must be disjoint',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    const jwe = { ...fullJwe }\n    jwe.unprotected = { enc: 'A128GCM' }\n\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), {\n      message: 'missing JWE Algorithm (alg) in JWE Header',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    const jwe = { ...fullJwe }\n    jwe.unprotected = { alg: 'dir' }\n\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), {\n      message: 'missing JWE Encryption Algorithm (enc) in JWE Header',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    const jwe = { ...fullJwe }\n    jwe.encrypted_key = 'foo'\n\n    await t.throwsAsync(flattenedDecrypt(jwe, t.context.secret), {\n      message: 'Encountered unexpected JWE Encrypted Key',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n})\n\ntest('AES CBC + HMAC', async (t) => {\n  const secret = crypto.randomFillSync(new Uint8Array(32))\n  const jwe = await new FlattenedEncrypt(t.context.plaintext)\n    .setProtectedHeader({ alg: 'dir', enc: 'A128CBC-HS256' })\n    .encrypt(secret)\n\n  await t.notThrowsAsync(flattenedDecrypt(jwe, secret))\n\n  {\n    const jweBadTag = { ...jwe }\n    jweBadTag.tag = 'foo'\n    await t.throwsAsync(flattenedDecrypt(jweBadTag, secret), {\n      code: 'ERR_JWE_DECRYPTION_FAILED',\n      message: 'decryption operation failed',\n    })\n  }\n\n  {\n    const jweBadEnc = { ...jwe }\n    jweBadEnc.ciphertext = 'foo'\n    await t.throwsAsync(flattenedDecrypt(jweBadEnc, secret), {\n      code: 'ERR_JWE_DECRYPTION_FAILED',\n      message: 'decryption operation failed',\n    })\n  }\n\n  {\n    const altSecret = new Uint8Array(32)\n    altSecret.set(secret.slice(0, 16), 16)\n    altSecret.set(secret.slice(16), 0)\n    await t.throwsAsync(flattenedDecrypt(jwe, altSecret), {\n      code: 'ERR_JWE_DECRYPTION_FAILED',\n      message: 'decryption operation failed',\n    })\n  }\n})\n\ntest('decrypt PBES2 p2c limit', async (t) => {\n  const jwe = await new FlattenedEncrypt(new Uint8Array(0))\n    .setProtectedHeader({ alg: 'PBES2-HS256+A128KW', enc: 'A128CBC-HS256' })\n    .setKeyManagementParameters({ p2c: 2049 })\n    .encrypt(new Uint8Array(32))\n\n  await t.notThrowsAsync(\n    flattenedDecrypt(jwe, new Uint8Array(32), { keyManagementAlgorithms: ['PBES2-HS256+A128KW'] }),\n  )\n\n  await t.throwsAsync(\n    flattenedDecrypt(jwe, new Uint8Array(32), {\n      maxPBES2Count: 2048,\n      keyManagementAlgorithms: ['PBES2-HS256+A128KW'],\n    }),\n    {\n      message: 'JOSE Header \"p2c\" (PBES2 Count) out is of acceptable bounds',\n      code: 'ERR_JWE_INVALID',\n    },\n  )\n})\n\ntest('decrypt with PBES2 is not allowed by default', async (t) => {\n  const jwe = await new FlattenedEncrypt(new Uint8Array(0))\n    .setProtectedHeader({ alg: 'PBES2-HS256+A128KW', enc: 'A128CBC-HS256' })\n    .encrypt(new Uint8Array(32))\n\n  await t.throwsAsync(flattenedDecrypt(jwe, new Uint8Array(32)), {\n    message: '\"alg\" (Algorithm) Header Parameter value not allowed',\n    code: 'ERR_JOSE_ALG_NOT_ALLOWED',\n  })\n})\n"
  },
  {
    "path": "test/jwe/flattened.encrypt.test.ts",
    "content": "import test from 'ava'\n\nimport { FlattenedEncrypt, decodeProtectedHeader } from '../../src/index.js'\n\ntest.before(async (t) => {\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n  t.context.plaintext = encode('It’s a dangerous business, Frodo, going out your door.')\n  t.context.additionalAuthenticatedData = encode('The Fellowship of the Ring')\n  t.context.initializationVector = new Uint8Array(12)\n  t.context.secret = new Uint8Array(16)\n})\n\ntest('FlattenedEncrypt', async (t) => {\n  {\n    const jwe = await new FlattenedEncrypt(t.context.plaintext)\n      .setInitializationVector(t.context.initializationVector)\n      .setProtectedHeader({ alg: 'dir' })\n      .setUnprotectedHeader({ enc: 'A128GCM' })\n      .encrypt(t.context.secret)\n    t.deepEqual(jwe, {\n      ciphertext: 'Svw4TvnFg_PTTKPXFteMF4Lmisk8ODBNko7607TNs49EbT0BKRz9tEep2dmks9KPvD-CfX7hW1M',\n      header: {\n        enc: 'A128GCM',\n      },\n      iv: 'AAAAAAAAAAAAAAAA',\n      protected: 'eyJhbGciOiJkaXIifQ',\n      tag: 'OYBq53cJNorm8LoZf4SwsA',\n    })\n  }\n  {\n    const jwe = await new FlattenedEncrypt(t.context.plaintext)\n      .setInitializationVector(t.context.initializationVector)\n      .setProtectedHeader({ alg: 'dir' })\n      .setSharedUnprotectedHeader({ enc: 'A128GCM' })\n      .encrypt(t.context.secret)\n    t.deepEqual(jwe, {\n      ciphertext: 'Svw4TvnFg_PTTKPXFteMF4Lmisk8ODBNko7607TNs49EbT0BKRz9tEep2dmks9KPvD-CfX7hW1M',\n      unprotected: {\n        enc: 'A128GCM',\n      },\n      iv: 'AAAAAAAAAAAAAAAA',\n      protected: 'eyJhbGciOiJkaXIifQ',\n      tag: 'OYBq53cJNorm8LoZf4SwsA',\n    })\n  }\n  {\n    const jwe = await new FlattenedEncrypt(t.context.plaintext)\n      .setInitializationVector(t.context.initializationVector)\n      .setSharedUnprotectedHeader({ alg: 'dir', enc: 'A128GCM' })\n      .encrypt(t.context.secret)\n    t.deepEqual(jwe, {\n      ciphertext: 'Svw4TvnFg_PTTKPXFteMF4Lmisk8ODBNko7607TNs49EbT0BKRz9tEep2dmks9KPvD-CfX7hW1M',\n      unprotected: {\n        alg: 'dir',\n        enc: 'A128GCM',\n      },\n      iv: 'AAAAAAAAAAAAAAAA',\n      tag: 'vrBCoJmYwG3M6xCZ5VSR3g',\n    })\n  }\n  {\n    const jwe = await new FlattenedEncrypt(t.context.plaintext)\n      .setInitializationVector(t.context.initializationVector)\n      .setProtectedHeader({ alg: 'dir' })\n      .setAdditionalAuthenticatedData(t.context.additionalAuthenticatedData)\n      .setSharedUnprotectedHeader({ enc: 'A128GCM' })\n      .encrypt(t.context.secret)\n    t.deepEqual(jwe, {\n      aad: 'VGhlIEZlbGxvd3NoaXAgb2YgdGhlIFJpbmc',\n      ciphertext: 'Svw4TvnFg_PTTKPXFteMF4Lmisk8ODBNko7607TNs49EbT0BKRz9tEep2dmks9KPvD-CfX7hW1M',\n      unprotected: {\n        enc: 'A128GCM',\n      },\n      iv: 'AAAAAAAAAAAAAAAA',\n      protected: 'eyJhbGciOiJkaXIifQ',\n      tag: 'gEwNlfPZ-O-dG7dTFkhMyQ',\n    })\n  }\n  {\n    for (const value of [\n      undefined,\n      null,\n      {},\n      '',\n      'foo',\n      1,\n      0,\n      true,\n      false,\n      [],\n      new FlattenedEncrypt(new Uint8Array()),\n    ]) {\n      t.throws(() => new FlattenedEncrypt(value), {\n        instanceOf: TypeError,\n        message: 'plaintext must be an instance of Uint8Array',\n      })\n    }\n  }\n})\n\ntest('FlattenedEncrypt.prototype.setProtectedHeader', (t) => {\n  t.throws(\n    () => new FlattenedEncrypt(t.context.plaintext).setProtectedHeader({}).setProtectedHeader({}),\n    {\n      instanceOf: TypeError,\n      message: 'setProtectedHeader can only be called once',\n    },\n  )\n})\n\ntest('FlattenedEncrypt.prototype.setUnprotectedHeader', (t) => {\n  t.throws(\n    () =>\n      new FlattenedEncrypt(t.context.plaintext).setUnprotectedHeader({}).setUnprotectedHeader({}),\n    {\n      instanceOf: TypeError,\n      message: 'setUnprotectedHeader can only be called once',\n    },\n  )\n})\n\ntest('FlattenedEncrypt.prototype.setSharedUnprotectedHeader', (t) => {\n  t.throws(\n    () =>\n      new FlattenedEncrypt(t.context.plaintext)\n        .setSharedUnprotectedHeader({})\n        .setSharedUnprotectedHeader({}),\n    {\n      instanceOf: TypeError,\n      message: 'setSharedUnprotectedHeader can only be called once',\n    },\n  )\n})\n\ntest('FlattenedEncrypt.prototype.setInitializationVector', (t) => {\n  t.throws(\n    () =>\n      new FlattenedEncrypt(t.context.plaintext)\n        .setInitializationVector(t.context.initializationVector)\n        .setInitializationVector(t.context.initializationVector),\n    {\n      instanceOf: TypeError,\n      message: 'setInitializationVector can only be called once',\n    },\n  )\n})\n\ntest('FlattenedEncrypt.prototype.setContentEncryptionKey', (t) => {\n  t.throws(\n    () =>\n      new FlattenedEncrypt(t.context.plaintext)\n        .setContentEncryptionKey(t.context.secret)\n        .setContentEncryptionKey(t.context.secret),\n    {\n      instanceOf: TypeError,\n      message: 'setContentEncryptionKey can only be called once',\n    },\n  )\n})\n\ntest('FlattenedEncrypt.prototype.encrypt must have a JOSE header', async (t) => {\n  await t.throwsAsync(new FlattenedEncrypt(t.context.plaintext).encrypt(t.context.secret), {\n    code: 'ERR_JWE_INVALID',\n    message:\n      'either setProtectedHeader, setUnprotectedHeader, or sharedUnprotectedHeader must be called before #encrypt()',\n  })\n})\n\ntest('FlattenedEncrypt.prototype.encrypt JOSE header must be disjoint', async (t) => {\n  await t.throwsAsync(\n    new FlattenedEncrypt(t.context.plaintext)\n      .setProtectedHeader({ alg: 'dir', enc: 'A128GCM' })\n      .setUnprotectedHeader({ alg: 'dir' })\n      .encrypt(t.context.secret),\n    {\n      code: 'ERR_JWE_INVALID',\n      message:\n        'JWE Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint',\n    },\n  )\n  await t.throwsAsync(\n    new FlattenedEncrypt(t.context.plaintext)\n      .setProtectedHeader({ alg: 'dir', enc: 'A128GCM' })\n      .setSharedUnprotectedHeader({ alg: 'dir' })\n      .encrypt(t.context.secret),\n    {\n      code: 'ERR_JWE_INVALID',\n      message:\n        'JWE Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint',\n    },\n  )\n})\n\ntest('FlattenedEncrypt.prototype.encrypt JOSE header have an alg', async (t) => {\n  await t.throwsAsync(\n    new FlattenedEncrypt(t.context.plaintext)\n      .setProtectedHeader({ enc: 'A128GCM' })\n      .encrypt(t.context.secret),\n    {\n      code: 'ERR_JWE_INVALID',\n      message: 'JWE \"alg\" (Algorithm) Header Parameter missing or invalid',\n    },\n  )\n})\n\ntest('FlattenedEncrypt.prototype.encrypt JOSE header have an enc', async (t) => {\n  await t.throwsAsync(\n    new FlattenedEncrypt(t.context.plaintext)\n      .setProtectedHeader({ alg: 'dir' })\n      .encrypt(t.context.secret),\n    {\n      code: 'ERR_JWE_INVALID',\n      message: 'JWE \"enc\" (Encryption Algorithm) Header Parameter missing or invalid',\n    },\n  )\n})\n\ntest('Default PBES2 Count', async (t) => {\n  t.is(\n    decodeProtectedHeader(\n      await new FlattenedEncrypt(t.context.plaintext)\n        .setProtectedHeader({ alg: 'PBES2-HS256+A128KW', enc: 'A128GCM' })\n        .encrypt(t.context.secret),\n    ).p2c,\n    2048,\n  )\n})\n"
  },
  {
    "path": "test/jwe/general.test.ts",
    "content": "import test from 'ava'\nimport * as crypto from 'crypto'\n\nimport { GeneralEncrypt, generalDecrypt, generateKeyPair } from '../../src/index.js'\n\ntest.before(async (t) => {\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n  t.context.plaintext = encode('It’s a dangerous business, Frodo, going out your door.')\n  t.context.additionalAuthenticatedData = encode('The Fellowship of the Ring')\n  t.context.initializationVector = crypto.randomFillSync(new Uint8Array(12))\n  t.context.secret = crypto.randomFillSync(new Uint8Array(32))\n  t.context.secret2 = crypto.randomFillSync(new Uint8Array(16))\n})\n\ntest('General JWE encryption', async (t) => {\n  const generalJwe = await new GeneralEncrypt(t.context.plaintext)\n    .setAdditionalAuthenticatedData(t.context.additionalAuthenticatedData)\n    .setProtectedHeader({ enc: 'A256GCM' })\n    .setSharedUnprotectedHeader({ foo: 'bar' })\n    .addRecipient(t.context.secret)\n    .setUnprotectedHeader({ alg: 'A256GCMKW' })\n    .addRecipient(t.context.secret2)\n    .setUnprotectedHeader({ alg: 'A128GCMKW' })\n    .encrypt()\n\n  t.true(generalJwe.aad && typeof generalJwe.aad === 'string')\n  t.true(generalJwe.ciphertext && typeof generalJwe.ciphertext === 'string')\n  t.true(generalJwe.iv && typeof generalJwe.iv === 'string')\n  t.true(generalJwe.protected && typeof generalJwe.protected === 'string')\n  t.true(\n    generalJwe.unprotected &&\n      typeof generalJwe.unprotected === 'object' &&\n      Object.keys(generalJwe.unprotected).length === 1,\n  )\n  t.true(generalJwe.tag && typeof generalJwe.tag === 'string')\n  t.is(generalJwe.recipients.length, 2)\n\n  for (const recipient of generalJwe.recipients) {\n    t.true(recipient.encrypted_key && typeof recipient.encrypted_key === 'string')\n    t.true(\n      recipient.header &&\n        typeof recipient.header === 'object' &&\n        Object.keys(recipient.header).length !== 0,\n    )\n  }\n\n  for (const secret of [t.context.secret, t.context.secret2]) {\n    await generalDecrypt(generalJwe, secret)\n  }\n})\n\ntest('General JWE encryption (single recipient dir)', async (t) => {\n  const generalJwe = await new GeneralEncrypt(t.context.plaintext)\n    .setAdditionalAuthenticatedData(t.context.additionalAuthenticatedData)\n    .setProtectedHeader({ enc: 'A256GCM' })\n    .setSharedUnprotectedHeader({ alg: 'A256GCMKW' })\n    .addRecipient(t.context.secret)\n    .encrypt()\n\n  t.true(generalJwe.aad && typeof generalJwe.aad === 'string')\n  t.true(generalJwe.ciphertext && typeof generalJwe.ciphertext === 'string')\n  t.true(generalJwe.iv && typeof generalJwe.iv === 'string')\n  t.true(generalJwe.protected && typeof generalJwe.protected === 'string')\n  t.true(generalJwe.tag && typeof generalJwe.tag === 'string')\n  t.true(\n    generalJwe.unprotected &&\n      typeof generalJwe.unprotected === 'object' &&\n      Object.keys(generalJwe.unprotected).length === 1,\n  )\n  t.is(generalJwe.recipients.length, 1)\n\n  t.true(\n    generalJwe.recipients[0].encrypted_key &&\n      typeof generalJwe.recipients[0].encrypted_key === 'string',\n  )\n  t.false('header' in generalJwe.recipients[0])\n\n  await generalDecrypt(generalJwe, t.context.secret)\n})\n\ntest('General JWE encryption (single recipient ECDH-ES)', async (t) => {\n  const kp = await generateKeyPair('ECDH-ES')\n  const generalJwe = await new GeneralEncrypt(t.context.plaintext)\n    .setAdditionalAuthenticatedData(t.context.additionalAuthenticatedData)\n    .setProtectedHeader({ enc: 'A256GCM' })\n    .setSharedUnprotectedHeader({ alg: 'ECDH-ES' })\n    .addRecipient(kp.publicKey)\n    .encrypt()\n\n  t.true(generalJwe.aad && typeof generalJwe.aad === 'string')\n  t.true(generalJwe.ciphertext && typeof generalJwe.ciphertext === 'string')\n  t.true(generalJwe.iv && typeof generalJwe.iv === 'string')\n  t.true(generalJwe.protected && typeof generalJwe.protected === 'string')\n  t.true(generalJwe.tag && typeof generalJwe.tag === 'string')\n  t.deepEqual(generalJwe.recipients, [{}])\n  t.true(\n    generalJwe.unprotected &&\n      typeof generalJwe.unprotected === 'object' &&\n      Object.keys(generalJwe.unprotected).length === 1,\n  )\n\n  await generalDecrypt(generalJwe, kp.privateKey)\n})\n\ntest('General JWE format validation', async (t) => {\n  const encrypt = new GeneralEncrypt(t.context.plaintext)\n    .setProtectedHeader({ bar: 'baz' })\n    .setSharedUnprotectedHeader({ foo: 'bar' })\n    .setAdditionalAuthenticatedData(t.context.additionalAuthenticatedData)\n\n  encrypt.addRecipient(t.context.secret).setUnprotectedHeader({ alg: 'A256GCMKW', enc: 'A256GCM' })\n\n  const generalJwe = await encrypt.encrypt()\n\n  {\n    await t.throwsAsync(generalDecrypt(null, t.context.secret), {\n      message: 'General JWE must be an object',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    await t.throwsAsync(generalDecrypt({ recipients: null }, t.context.secret), {\n      message: 'JWE Recipients missing or incorrect type',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    await t.throwsAsync(generalDecrypt({ recipients: [null] }, t.context.secret), {\n      message: 'JWE Recipients missing or incorrect type',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    const jwe = { ...generalJwe, recipients: [] }\n\n    await t.throwsAsync(generalDecrypt(jwe, t.context.secret), {\n      message: 'JWE Recipients has no members',\n      code: 'ERR_JWE_INVALID',\n    })\n  }\n\n  {\n    const jwe = { ...generalJwe, recipients: [{}] }\n\n    await t.throwsAsync(generalDecrypt(jwe, t.context.secret), {\n      message: 'decryption operation failed',\n      code: 'ERR_JWE_DECRYPTION_FAILED',\n    })\n  }\n\n  {\n    const jwe = { ...generalJwe, recipients: [generalJwe.recipients[0]] }\n\n    await t.notThrowsAsync(generalDecrypt(jwe, t.context.secret))\n  }\n\n  {\n    const jwe = { ...generalJwe, recipients: [generalJwe.recipients[0], {}] }\n\n    await t.notThrowsAsync(generalDecrypt(jwe, t.context.secret))\n  }\n\n  {\n    const jwe = { ...generalJwe, recipients: [{}, generalJwe.recipients[0]] }\n\n    await t.notThrowsAsync(generalDecrypt(jwe, t.context.secret))\n  }\n})\n\ntest('Default PBES2 Count', async (t) => {\n  const jwe = await new GeneralEncrypt(t.context.plaintext)\n    .setProtectedHeader({ alg: 'PBES2-HS256+A128KW', enc: 'A128GCM' })\n    .addRecipient(t.context.secret)\n    .addRecipient(t.context.secret)\n    .encrypt(t.context.secret)\n\n  const [{ header: bob }, { header: charlie }] = jwe.recipients\n  t.is(bob.p2c, 2048)\n  t.is(charlie.p2c, 2048)\n  t.true(bob.p2s !== charlie.p2s)\n})\n"
  },
  {
    "path": "test/jwe/zip.test.ts",
    "content": "import test from 'ava'\nimport * as crypto from 'node:crypto'\n\nimport {\n  FlattenedEncrypt,\n  flattenedDecrypt,\n  CompactEncrypt,\n  compactDecrypt,\n  GeneralEncrypt,\n  generalDecrypt,\n  EncryptJWT,\n  jwtDecrypt,\n  generateSecret,\n} from '../../src/index.js'\n\nconst hasCompressionStreams = typeof globalThis.CompressionStream !== 'undefined'\n\nconst encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n\ntest.before(async (t) => {\n  t.context.plaintext = encode(\"It's a dangerous business, Frodo, going out your door.\")\n  t.context.secret = await generateSecret('A128GCM')\n})\n\nif (hasCompressionStreams) {\n  test('FlattenedEncrypt/flattenedDecrypt with zip: DEF', async (t) => {\n    const jwe = await new FlattenedEncrypt(t.context.plaintext)\n      .setProtectedHeader({ alg: 'dir', enc: 'A128GCM', zip: 'DEF' })\n      .encrypt(t.context.secret)\n\n    const { plaintext } = await flattenedDecrypt(jwe, t.context.secret)\n    t.deepEqual(plaintext, t.context.plaintext)\n  })\n\n  test('CompactEncrypt/compactDecrypt with zip: DEF', async (t) => {\n    const jwe = await new CompactEncrypt(t.context.plaintext)\n      .setProtectedHeader({ alg: 'dir', enc: 'A128GCM', zip: 'DEF' })\n      .encrypt(t.context.secret)\n\n    const { plaintext } = await compactDecrypt(jwe, t.context.secret)\n    t.deepEqual(plaintext, t.context.plaintext)\n  })\n\n  test('GeneralEncrypt/generalDecrypt with zip: DEF', async (t) => {\n    const jwe = await new GeneralEncrypt(t.context.plaintext)\n      .setProtectedHeader({ enc: 'A128GCM', zip: 'DEF' })\n      .addRecipient(t.context.secret)\n      .setUnprotectedHeader({ alg: 'A128GCMKW' })\n      .encrypt()\n\n    const { plaintext } = await generalDecrypt(jwe, t.context.secret)\n    t.deepEqual(plaintext, t.context.plaintext)\n  })\n\n  test('EncryptJWT/jwtDecrypt with zip: DEF', async (t) => {\n    const jwt = await new EncryptJWT({ foo: 'bar' })\n      .setProtectedHeader({ alg: 'dir', enc: 'A128GCM', zip: 'DEF' })\n      .encrypt(t.context.secret)\n\n    const { payload, protectedHeader } = await jwtDecrypt(jwt, t.context.secret)\n    t.is(payload.foo, 'bar')\n    t.is(protectedHeader.zip, 'DEF')\n  })\n\n  test('jwtDecrypt with zip: DEF and maxDecompressedLength option', async (t) => {\n    const jwt = await new EncryptJWT({ foo: 'bar' })\n      .setProtectedHeader({ alg: 'dir', enc: 'A128GCM', zip: 'DEF' })\n      .encrypt(t.context.secret)\n\n    // Should succeed with a generous limit\n    await t.notThrowsAsync(jwtDecrypt(jwt, t.context.secret, { maxDecompressedLength: Infinity }))\n\n    // Should succeed with a reasonable limit\n    await t.notThrowsAsync(jwtDecrypt(jwt, t.context.secret, { maxDecompressedLength: 1024 }))\n  })\n\n  test('maxDecompressedLength: 0 disables zip support on decrypt', async (t) => {\n    const jwe = await new CompactEncrypt(t.context.plaintext)\n      .setProtectedHeader({ alg: 'dir', enc: 'A128GCM', zip: 'DEF' })\n      .encrypt(t.context.secret)\n\n    await t.throwsAsync(compactDecrypt(jwe, t.context.secret, { maxDecompressedLength: 0 }), {\n      message: 'JWE \"zip\" (Compression Algorithm) Header Parameter is not supported.',\n      code: 'ERR_JOSE_NOT_SUPPORTED',\n    })\n  })\n\n  test('maxDecompressedLength: Infinity disables bomb protection', async (t) => {\n    // Create a large plaintext\n    const largePlaintext = new Uint8Array(300_000)\n    const jwe = await new CompactEncrypt(largePlaintext)\n      .setProtectedHeader({ alg: 'dir', enc: 'A128GCM', zip: 'DEF' })\n      .encrypt(t.context.secret)\n\n    // Default limit (250KB) should reject\n    await t.throwsAsync(compactDecrypt(jwe, t.context.secret), {\n      message: 'Decompressed plaintext exceeded the configured limit',\n      code: 'ERR_JWE_INVALID',\n    })\n\n    // Infinity should allow\n    const { plaintext } = await compactDecrypt(jwe, t.context.secret, {\n      maxDecompressedLength: Infinity,\n    })\n    t.is(plaintext.byteLength, 300_000)\n  })\n\n  test('maxDecompressedLength enforcement', async (t) => {\n    const plaintext = new Uint8Array(1024)\n    const jwe = await new CompactEncrypt(plaintext)\n      .setProtectedHeader({ alg: 'dir', enc: 'A128GCM', zip: 'DEF' })\n      .encrypt(t.context.secret)\n\n    await t.throwsAsync(compactDecrypt(jwe, t.context.secret, { maxDecompressedLength: 512 }), {\n      message: 'Decompressed plaintext exceeded the configured limit',\n      code: 'ERR_JWE_INVALID',\n    })\n\n    await t.notThrowsAsync(compactDecrypt(jwe, t.context.secret, { maxDecompressedLength: 2048 }))\n  })\n\n  test('maxDecompressedLength must be 0, a positive safe integer, or Infinity', async (t) => {\n    const jwe = await new CompactEncrypt(t.context.plaintext)\n      .setProtectedHeader({ alg: 'dir', enc: 'A128GCM', zip: 'DEF' })\n      .encrypt(t.context.secret)\n\n    for (const value of [-1, 0.5, NaN, -Infinity]) {\n      await t.throwsAsync(compactDecrypt(jwe, t.context.secret, { maxDecompressedLength: value }), {\n        instanceOf: TypeError,\n        message: 'maxDecompressedLength must be 0, a positive safe integer, or Infinity',\n      })\n    }\n  })\n\n  test('invalid deflate data is properly rejected', async (t) => {\n    const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 2048 })\n    const cek = crypto.randomBytes(32)\n    const iv = crypto.randomBytes(12)\n    const protectedHeader = { alg: 'RSA-OAEP-256', enc: 'A256GCM', zip: 'DEF' }\n    const protectedB64 = Buffer.from(JSON.stringify(protectedHeader)).toString('base64url')\n\n    const cipher = crypto.createCipheriv('aes-256-gcm', cek, iv, { authTagLength: 16 })\n    cipher.setAAD(Buffer.from(protectedB64))\n    const ciphertext = Buffer.concat([cipher.update(new Uint8Array([0x00])), cipher.final()])\n    const tag = cipher.getAuthTag()\n    const encryptedKey = crypto.publicEncrypt({ key: publicKey, oaepHash: 'sha256' }, cek)\n\n    const flattened = {\n      protected: protectedB64,\n      encrypted_key: Buffer.from(encryptedKey).toString('base64url'),\n      iv: Buffer.from(iv).toString('base64url'),\n      ciphertext: Buffer.from(ciphertext).toString('base64url'),\n      tag: Buffer.from(tag).toString('base64url'),\n    }\n\n    await t.throwsAsync(flattenedDecrypt(flattened, privateKey), {\n      code: 'ERR_JWE_INVALID',\n      message: 'Failed to decompress plaintext',\n    })\n\n    t.pass()\n  })\n}\n\ntest('unsupported zip value on encrypt throws JOSENotSupported', async (t) => {\n  await t.throwsAsync(\n    new FlattenedEncrypt(t.context.plaintext)\n      .setProtectedHeader({ alg: 'dir', enc: 'A128GCM', zip: 'gzip' })\n      .encrypt(t.context.secret),\n    {\n      message: 'Unsupported JWE \"zip\" (Compression Algorithm) Header Parameter value.',\n      code: 'ERR_JOSE_NOT_SUPPORTED',\n    },\n  )\n})\n\ntest('zip must be in a protected header on encrypt', async (t) => {\n  await t.throwsAsync(\n    new FlattenedEncrypt(t.context.plaintext)\n      .setProtectedHeader({ alg: 'dir', enc: 'A128GCM' })\n      .setSharedUnprotectedHeader({ zip: 'DEF' })\n      .encrypt(t.context.secret),\n    {\n      message: 'JWE \"zip\" (Compression Algorithm) Header Parameter MUST be in a protected header.',\n      code: 'ERR_JWE_INVALID',\n    },\n  )\n\n  await t.throwsAsync(\n    new FlattenedEncrypt(t.context.plaintext)\n      .setProtectedHeader({ alg: 'dir', enc: 'A128GCM' })\n      .setUnprotectedHeader({ zip: 'DEF' })\n      .encrypt(t.context.secret),\n    {\n      message: 'JWE \"zip\" (Compression Algorithm) Header Parameter MUST be in a protected header.',\n      code: 'ERR_JWE_INVALID',\n    },\n  )\n})\n\ntest('zip must be in a protected header on encrypt (multi-recipient)', async (t) => {\n  const secret1 = await generateSecret('A128KW')\n  const secret2 = await generateSecret('A128KW')\n\n  await t.throwsAsync(\n    new GeneralEncrypt(t.context.plaintext)\n      .setProtectedHeader({ enc: 'A128GCM' })\n      .setSharedUnprotectedHeader({ zip: 'DEF' })\n      .addRecipient(secret1)\n      .setUnprotectedHeader({ alg: 'A128KW' })\n      .addRecipient(secret2)\n      .setUnprotectedHeader({ alg: 'A128KW' })\n      .encrypt(),\n    {\n      message: 'JWE \"zip\" (Compression Algorithm) Header Parameter MUST be in a protected header.',\n      code: 'ERR_JWE_INVALID',\n    },\n  )\n\n  await t.throwsAsync(\n    new GeneralEncrypt(t.context.plaintext)\n      .setProtectedHeader({ enc: 'A128GCM' })\n      .addRecipient(secret1)\n      .setUnprotectedHeader({ alg: 'A128KW' })\n      .addRecipient(secret2)\n      .setUnprotectedHeader({ alg: 'A128KW', zip: 'DEF' })\n      .encrypt(),\n    {\n      message: 'JWE \"zip\" (Compression Algorithm) Header Parameter MUST be in a protected header.',\n      code: 'ERR_JWE_INVALID',\n    },\n  )\n})\n\ntest('zip must be in a protected header on decrypt', async (t) => {\n  const jwe = await new FlattenedEncrypt(t.context.plaintext)\n    .setProtectedHeader({ alg: 'dir', enc: 'A128GCM' })\n    .encrypt(t.context.secret)\n\n  // Tamper: put zip in unprotected header\n  const tampered = { ...jwe, unprotected: { zip: 'DEF' } }\n  await t.throwsAsync(flattenedDecrypt(tampered, t.context.secret), {\n    message: 'JWE \"zip\" (Compression Algorithm) Header Parameter MUST be in a protected header.',\n    code: 'ERR_JWE_INVALID',\n  })\n\n  // Tamper: put zip in per-recipient header\n  const tampered2 = { ...jwe, header: { zip: 'DEF' } }\n  await t.throwsAsync(flattenedDecrypt(tampered2, t.context.secret), {\n    message: 'JWE \"zip\" (Compression Algorithm) Header Parameter MUST be in a protected header.',\n    code: 'ERR_JWE_INVALID',\n  })\n})\n\ntest('unsupported zip value on decrypt throws JOSENotSupported', async (t) => {\n  // Build a JWE without zip, then tamper the protected header to have zip: gzip\n  const jwe = await new FlattenedEncrypt(t.context.plaintext)\n    .setProtectedHeader({ alg: 'dir', enc: 'A128GCM' })\n    .encrypt(t.context.secret)\n\n  // Replace protected header with one containing zip: gzip\n  const tampered = {\n    ...jwe,\n    protected: btoa(JSON.stringify({ alg: 'dir', enc: 'A128GCM', zip: 'gzip' }))\n      .replace(/\\+/g, '-')\n      .replace(/\\//g, '_')\n      .replace(/=+$/, ''),\n  }\n\n  await t.throwsAsync(flattenedDecrypt(tampered, t.context.secret), {\n    code: 'ERR_JOSE_NOT_SUPPORTED',\n  })\n})\n\nif (!hasCompressionStreams) {\n  test('zip: DEF throws JOSENotSupported when CompressionStream is unavailable', async (t) => {\n    await t.throwsAsync(\n      new FlattenedEncrypt(t.context.plaintext)\n        .setProtectedHeader({ alg: 'dir', enc: 'A128GCM', zip: 'DEF' })\n        .encrypt(t.context.secret),\n      {\n        code: 'ERR_JOSE_NOT_SUPPORTED',\n      },\n    )\n  })\n}\n"
  },
  {
    "path": "test/jwk/embedded.test.ts",
    "content": "import test from 'ava'\n\nimport { importJWK, EmbeddedJWK, FlattenedSign, flattenedVerify } from '../../src/index.js'\n\nfunction pubjwk(jwk) {\n  const { d, p, q, dp, dq, qi, ext, alg, ...publicJwk } = jwk\n  return publicJwk\n}\n\ntest.before(async (t) => {\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n  t.context.key = {\n    crv: 'P-256',\n    alg: 'ES256',\n    ext: false,\n    x: 'Sp3KpzPjwcCF04_W2GvSSf-vGDvp3Iv2kQYqAjnMB-Y',\n    y: 'lZmecT2quXe0i9f7b4qHvDAFDpxs0oxCoJx4tOOqsks',\n    d: 'hRVo5TGE_d_4tQC1KEQIlCdo9rteZmLSmaMPpFOjeDI',\n    kty: 'EC',\n  }\n\n  const privateKey = await importJWK(t.context.key)\n  t.context.token = await new FlattenedSign(\n    encode('It’s a dangerous business, Frodo, going out your door.'),\n  )\n    .setProtectedHeader({ alg: 'ES256', jwk: pubjwk(t.context.key) })\n    .sign(privateKey)\n  t.context.tokenMissingJwk = await new FlattenedSign(\n    encode('It’s a dangerous business, Frodo, going out your door.'),\n  )\n    .setProtectedHeader({ alg: 'ES256' })\n    .sign(privateKey)\n  t.context.tokenInvalidJWK = await new FlattenedSign(\n    encode('It’s a dangerous business, Frodo, going out your door.'),\n  )\n    .setProtectedHeader({ alg: 'ES256', jwk: null })\n    .sign(privateKey)\n  t.context.tokenPrivateJWK = await new FlattenedSign(\n    encode('It’s a dangerous business, Frodo, going out your door.'),\n  )\n    .setProtectedHeader({ alg: 'ES256', jwk: t.context.key })\n    .sign(privateKey)\n})\n\ntest('EmbeddedJWK', async (t) => {\n  await t.notThrowsAsync(async () => {\n    const { key: resolvedKey } = await flattenedVerify(t.context.token, EmbeddedJWK)\n    t.truthy(resolvedKey)\n    t.is(resolvedKey.type, 'public')\n  })\n})\n\ntest('EmbeddedJWK requires \"jwk\" to be an object', async (t) => {\n  await t.throwsAsync(flattenedVerify(t.context.tokenMissingJwk, EmbeddedJWK), {\n    code: 'ERR_JWS_INVALID',\n    message: '\"jwk\" (JSON Web Key) Header Parameter must be a JSON object',\n  })\n  await t.throwsAsync(flattenedVerify(t.context.tokenInvalidJWK, EmbeddedJWK), {\n    code: 'ERR_JWS_INVALID',\n    message: '\"jwk\" (JSON Web Key) Header Parameter must be a JSON object',\n  })\n})\n\ntest('EmbeddedJWK requires \"jwk\" to be a public one', async (t) => {\n  await t.throwsAsync(flattenedVerify(t.context.tokenPrivateJWK, EmbeddedJWK), {\n    code: 'ERR_JWS_INVALID',\n    message: '\"jwk\" (JSON Web Key) Header Parameter must be a public key',\n  })\n})\n"
  },
  {
    "path": "test/jwk/issue-459.test.ts",
    "content": "import test from 'ava'\n\nimport { importX509 } from '../../src/index.js'\n\nconst cert = `-----BEGIN CERTIFICATE-----\nMIID5jCCAs6gAwIBAgIBAjANBgkqhkiG9w0BAQsFADB7MQswCQYDVQQGEwJVUzEL\nMAkGA1UECBMCVE4xEDAOBgNVBAoTB01TSUdOSUExDDAKBgNVBAsTA1JORDEXMBUG\nA1UEAxMOTVNJR05JQSBSTkQgQ0ExJjAkBgkqhkiG9w0BCQEWF3BhdmxvLmx5c292\nQG1zaWduaWEuY29tMB4XDTE5MTExMzA4MjAwMFoXDTI4MTExMzA4MjAwMFowgYAx\nCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJUTjEQMA4GA1UEChMHTVNJR05JQTEUMBIG\nA1UECxMLTVNJR05JQSBSTkQxFDASBgNVBAMTC01TSUdOSUEgUk5EMSYwJAYJKoZI\nhvcNAQkBFhdwYXZsby5seXNvdkBtc2lnbmlhLmNvbTCCASIwDQYJKoZIhvcNAQEB\nBQADggEPADCCAQoCggEBAKRoo30zttpiFlBKnOAmlOcT07xPms7Z6/ZdN9KnE/Po\nNQx7g6+Ap6b+trA2WDG80jEtwAy5XJcm81rBvJJvjwWQhiPjhXHvEibl+5zTYEXQ\ntvl3qKNdikXuXPBLI/rwmZTNZd2aa5biVoLEY+cQVLOjdAZS9ZIkeuLYeLEZfNky\n7rLa4XyRO4W4XEUWgafOp+ZSXATOz48XCb+fmaek4d8epsVJ/X3Qww9I9mqg8QA7\n/EH9ASOYvbMzOjSuDjYBCRq4SJw/YBJDnBcBJSESzLJDDCJQyP4BOD2+P5UZ/OWS\nNyzEDCLfLsiCVjdt0mNXrn/tGpdLoy1rVfC2SOAoZEUCAwEAAaNvMG0wDAYDVR0T\nAQH/BAIwADAdBgNVHQ4EFgQUU/luo/bbBOlrQ7wrC3+ggkITcSYwCwYDVR0PBAQD\nAgSwMBEGCWCGSAGG+EIBAQQEAwIFoDAeBglghkgBhvhCAQ0EERYPeGNhIGNlcnRp\nZmljYXRlMA0GCSqGSIb3DQEBCwUAA4IBAQAXroFZ9FeP10gtQguptDo6U0SIAB9n\nqjN1IktyqatfUuVtThuxXAb3QQ7kYmGCZEaOIKoFdVc8i9aR5ZrYC1VIN4+cGLv7\nP36Zl2q4i2G/X0QzniPPvsPyOUXeTVs3k6Sxe07uWdxsglq9LcVW++PvGYzotZP+\nZtmTzYAQtgadhPNo7+QmTO1FDju9p9hTFK7WhmXAO48bF9jrFiTkbwmo6PdlQiqi\nPQYlbfO0XV727QUZ1YyG8rR/3VVRsBOmwZBKCj0dkh9eiRcNpJloqe1uZ83EBG/W\nCic5wE9P+Ol/pFNJFpfjXMsmT8lkCK954aYf2xoH1bHkONYAEEk0iQu/\n-----END CERTIFICATE-----`\n\ntest('https://github.com/panva/jose/issues/459', (t) => {\n  return t.notThrowsAsync(() => importX509(cert, 'RS256'))\n})\n"
  },
  {
    "path": "test/jwk/jwk2key.test.ts",
    "content": "import test from 'ava'\n\nimport { importJWK, exportJWK } from '../../src/index.js'\n\ntest('JWK must be an object', async (t) => {\n  await t.throwsAsync(importJWK(true), {\n    instanceOf: TypeError,\n    message: 'JWK must be an object',\n  })\n  await t.throwsAsync(importJWK(null), {\n    instanceOf: TypeError,\n    message: 'JWK must be an object',\n  })\n  await t.throwsAsync(importJWK(Boolean), {\n    instanceOf: TypeError,\n    message: 'JWK must be an object',\n  })\n  await t.throwsAsync(importJWK([]), {\n    instanceOf: TypeError,\n    message: 'JWK must be an object',\n  })\n  await t.throwsAsync(importJWK(''), {\n    instanceOf: TypeError,\n    message: 'JWK must be an object',\n  })\n  const nullPrototype = Object.create(null)\n  nullPrototype.crv = 'P-256'\n  nullPrototype.kty = 'EC'\n  nullPrototype.x = 'q3zAwR_kUwtdLEwtB2oVfucXiLHmEhu9bJUFYjJxYGs'\n  nullPrototype.y = '8h0D-ONoU-iZqrq28TyUxEULxuGwJZGMJYTMbeMshvI'\n  await t.notThrowsAsync(importJWK(nullPrototype, 'ES256'))\n})\n\ntest('JWK kty must be recognized', async (t) => {\n  await t.throwsAsync(importJWK({ kty: 'unrecognized' }, 'HS256'), {\n    code: 'ERR_JOSE_NOT_SUPPORTED',\n    message: 'Unsupported \"kty\" (Key Type) Parameter value',\n  })\n})\n\ntest('oct JWK must have \"k\"', async (t) => {\n  await t.throwsAsync(importJWK({ kty: 'oct' }, 'HS256'), {\n    instanceOf: TypeError,\n    message: 'missing \"k\" (Key Value) Parameter value',\n  })\n})\n\ntest('RSA JWK with oth is not supported', async (t) => {\n  await t.throwsAsync(importJWK({ kty: 'RSA', oth: [] }, 'RS256'), {\n    code: 'ERR_JOSE_NOT_SUPPORTED',\n    message: 'RSA JWK \"oth\" (Other Primes Info) Parameter value is not supported',\n  })\n})\n\ntest('oct JWK', async (t) => {\n  const oct = {\n    k: 'FyCq1CKBflh3I5gikEjpYrdOXllzxB_yc02za8ERknI',\n    kty: 'oct',\n  }\n\n  t.deepEqual(\n    [...(await importJWK(oct, 'HS256'))],\n    [\n      23, 32, 170, 212, 34, 129, 126, 88, 119, 35, 152, 34, 144, 72, 233, 98, 183, 78, 94, 89, 115,\n      196, 31, 242, 115, 77, 179, 107, 193, 17, 146, 114,\n    ],\n  )\n})\n\ntest('Uin8tArray can be transformed to a JWK', async (t) => {\n  t.deepEqual(\n    await exportJWK(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])),\n    {\n      k: 'AQIDBAUGBwgJCgsMDQ4P',\n      kty: 'oct',\n    },\n  )\n})\n\ntest('secret KeyLike can be transformed to a JWK', async (t) => {\n  const keylike = await importJWK(\n    {\n      ext: true,\n      k: 'AQIDBAUGBwgJCgsMDQ4P',\n      kty: 'oct',\n    },\n    'HS256',\n  )\n  t.deepEqual(await exportJWK(keylike), {\n    k: 'AQIDBAUGBwgJCgsMDQ4P',\n    kty: 'oct',\n  })\n})\n"
  },
  {
    "path": "test/jwk/thumbprint.test.ts",
    "content": "import test from 'ava'\n\nimport { calculateJwkThumbprint, calculateJwkThumbprintUri } from '../../src/index.js'\n\nconst jwk = {\n  kty: 'RSA',\n  n: '0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw',\n  e: 'AQAB',\n  alg: 'RS256',\n}\n\ntest('https://www.rfc-editor.org/rfc/rfc7638#section-3.1', async (t) => {\n  t.is(await calculateJwkThumbprint(jwk), 'NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs')\n  t.is(await calculateJwkThumbprint(jwk, 'sha256'), 'NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs')\n  t.is(\n    await calculateJwkThumbprint(jwk, 'sha384'),\n    'R9_OfJjSjaw8Fuum86UzK5ixTdN9bo9BaqPSiseq89DWfmqCdpSgUHus-cxDUNc8',\n  )\n  t.is(\n    await calculateJwkThumbprint(jwk, 'sha512'),\n    'DpvEwocfn3FjeWWQjcJHzWrpKTIymKwgoL1xVgQcud48-qZDSRCr1zfWZQdHAJn_ciqXqPTSARyg-L-NyNGpVA',\n  )\n})\n\ntest('https://www.rfc-editor.org/rfc/rfc9278', async (t) => {\n  t.is(\n    await calculateJwkThumbprintUri(jwk),\n    'urn:ietf:params:oauth:jwk-thumbprint:sha-256:NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs',\n  )\n  t.is(\n    await calculateJwkThumbprintUri(jwk, 'sha256'),\n    'urn:ietf:params:oauth:jwk-thumbprint:sha-256:NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs',\n  )\n  t.is(\n    await calculateJwkThumbprintUri(jwk, 'sha384'),\n    'urn:ietf:params:oauth:jwk-thumbprint:sha-384:R9_OfJjSjaw8Fuum86UzK5ixTdN9bo9BaqPSiseq89DWfmqCdpSgUHus-cxDUNc8',\n  )\n  t.is(\n    await calculateJwkThumbprintUri(jwk, 'sha512'),\n    'urn:ietf:params:oauth:jwk-thumbprint:sha-512:DpvEwocfn3FjeWWQjcJHzWrpKTIymKwgoL1xVgQcud48-qZDSRCr1zfWZQdHAJn_ciqXqPTSARyg-L-NyNGpVA',\n  )\n})\n\ntest('Key must be one of type CryptoKey, KeyObject, or JSON Web Key.', async (t) => {\n  await t.throwsAsync(calculateJwkThumbprint(true), {\n    instanceOf: TypeError,\n    message: /Key must be one of type CryptoKey, KeyObject, or JSON Web Key./,\n  })\n  await t.throwsAsync(calculateJwkThumbprint(null), {\n    instanceOf: TypeError,\n    message: /Key must be one of type CryptoKey, KeyObject, or JSON Web Key./,\n  })\n  await t.throwsAsync(calculateJwkThumbprint(Boolean), {\n    instanceOf: TypeError,\n    message: /Key must be one of type CryptoKey, KeyObject, or JSON Web Key./,\n  })\n  await t.throwsAsync(calculateJwkThumbprint([]), {\n    instanceOf: TypeError,\n    message: /Key must be one of type CryptoKey, KeyObject, or JSON Web Key./,\n  })\n  await t.throwsAsync(calculateJwkThumbprint(''), {\n    instanceOf: TypeError,\n    message: /Key must be one of type CryptoKey, KeyObject, or JSON Web Key./,\n  })\n  const nullPrototype = Object.create(null)\n  nullPrototype.crv = 'P-256'\n  nullPrototype.kty = 'EC'\n  nullPrototype.x = 'q3zAwR_kUwtdLEwtB2oVfucXiLHmEhu9bJUFYjJxYGs'\n  nullPrototype.y = '8h0D-ONoU-iZqrq28TyUxEULxuGwJZGMJYTMbeMshvI'\n  await t.notThrowsAsync(calculateJwkThumbprint(nullPrototype))\n})\n\ntest('JWK kty must be recognized', async (t) => {\n  await t.throwsAsync(calculateJwkThumbprint({ kty: 'unrecognized' }), {\n    code: 'ERR_JOSE_NOT_SUPPORTED',\n    message: '\"kty\" (Key Type) Parameter missing or unsupported',\n  })\n})\n\ntest('EC JWK', async (t) => {\n  const ec = {\n    crv: 'P-256',\n    kty: 'EC',\n    x: 'q3zAwR_kUwtdLEwtB2oVfucXiLHmEhu9bJUFYjJxYGs',\n    y: '8h0D-ONoU-iZqrq28TyUxEULxuGwJZGMJYTMbeMshvI',\n  }\n\n  await t.throwsAsync(calculateJwkThumbprint({ ...ec, crv: undefined }), {\n    code: 'ERR_JWK_INVALID',\n    message: '\"crv\" (Curve) Parameter missing or invalid',\n  })\n  await t.throwsAsync(calculateJwkThumbprint({ ...ec, x: undefined }), {\n    code: 'ERR_JWK_INVALID',\n    message: '\"x\" (X Coordinate) Parameter missing or invalid',\n  })\n  await t.throwsAsync(calculateJwkThumbprint({ ...ec, y: undefined }), {\n    code: 'ERR_JWK_INVALID',\n    message: '\"y\" (Y Coordinate) Parameter missing or invalid',\n  })\n  t.is(await calculateJwkThumbprint(ec), 'ZrBaai73Hi8Fg4MElvDGzIne2NsbI75RHubOViHYE5Q')\n})\n\ntest('OKP JWK', async (t) => {\n  const okp = {\n    crv: 'Ed25519',\n    kty: 'OKP',\n    x: '5fL1GDeyNTIxtuzTeFnvZTo4Oz0EkMfAdhIJA-EFn0w',\n  }\n\n  await t.throwsAsync(calculateJwkThumbprint({ ...okp, crv: undefined }), {\n    code: 'ERR_JWK_INVALID',\n    message: '\"crv\" (Subtype of Key Pair) Parameter missing or invalid',\n  })\n  await t.throwsAsync(calculateJwkThumbprint({ ...okp, x: undefined }), {\n    code: 'ERR_JWK_INVALID',\n    message: '\"x\" (Public Key) Parameter missing or invalid',\n  })\n  t.is(await calculateJwkThumbprint(okp), '1OzNmMHhNzbSJyoePAtdoVedRZlFvER3K3RAzCrfX0k')\n})\n\ntest('RSA JWK', async (t) => {\n  const rsa = {\n    e: 'AQAB',\n    kty: 'RSA',\n    n: 'ok6WYUlmj2J1p-Sm0kwaZlAbWetUooe2LR6iAOJfntavWlyBO0shK_550YG3lQ6R1YeKisNAqbQ1pjqo3vwvR_v_AWtZ1gY1h6KX4DhCv0nNMexZ4g67LxEweoQ4_InMMiwMyQ3CRVJ3P1w0TQZYqzfSye-llY39tyzHeHeuotgrZrM427iUuIJdN38nZ2vW9VpK3bo_Nsvl12ZBe6x7DBzWEFHqQDFyjy8lH8EZyxqDArLA7T5OAcEdkm3RI8jBbsrUD9IySCE5SdEU3n0VGNGkT88DFU85QGvLpL2ITbGX0amaJvxYjIRhIYTfZS6Mqoxr6K1LIwP8pu0VD2Ca5Q',\n  }\n\n  await t.throwsAsync(calculateJwkThumbprint({ ...rsa, e: undefined }), {\n    code: 'ERR_JWK_INVALID',\n    message: '\"e\" (Exponent) Parameter missing or invalid',\n  })\n  await t.throwsAsync(calculateJwkThumbprint({ ...rsa, n: undefined }), {\n    code: 'ERR_JWK_INVALID',\n    message: '\"n\" (Modulus) Parameter missing or invalid',\n  })\n  t.is(await calculateJwkThumbprint(rsa), 'dQiQXSGtV4XcPK143Cu2-ZSsQtVNjQZrleUMs9nLnKQ')\n})\n\ntest('oct JWK', async (t) => {\n  const oct = {\n    k: 'FyCq1CKBflh3I5gikEjpYrdOXllzxB_yc02za8ERknI',\n    kty: 'oct',\n  }\n\n  await t.throwsAsync(calculateJwkThumbprint({ ...oct, k: undefined }), {\n    code: 'ERR_JWK_INVALID',\n    message: '\"k\" (Key Value) Parameter missing or invalid',\n  })\n  t.is(await calculateJwkThumbprint(oct), 'prDKy90VJzrDTpm8-W2Q_pv_kzrX_zyZ7ANjRAasDxc')\n})\n\ntest('AKP JWK', async (t) => {\n  const akp = {\n    kty: 'AKP',\n    alg: 'ML-DSA-44',\n    pub: 'unH59k4RuutY-pxvu24U5h8YZD2rSVtHU5qRZsoBmBMcRPgmu9VuNOVdteXi1zNIXjnqJg_GAAxepLqA00Vc3lO0bzRIKu39VFD8Lhuk8l0V-cFEJC-zm7UihxiQMMUEmOFxe3x1ixkKZ0jqmqP3rKryx8tSbtcXyfea64QhT6XNje2SoMP6FViBDxLHBQo2dwjRls0k5a-XSQSu2OTOiHLoaWsLe8pQ5FLNfTDqmkrawDEdZyxr3oSWJAsHQxRjcIiVzZuvwxYy1zl2STiP2vy_fTBaPemkleynQzqPg7oPCyXEE8bjnJbrfWkbNNN8438e6tHPIX4l7zTuzz98YPhLjt_d6EBdT4MldsYe-Y4KLyjaGHcAlTkk9oa5RhRwW89T0z_t1DSO3dvfKLUGXh8gd1BD6Fz5MfgpF5NjoafnQEqDjsAAhrCXY4b-Y3yYJEdX4_dp3dRGdHG_rWcPmgX4JG7lCnser4f8QGnDriqiAzJYEXeS8LzUngg_0bx0lqv_KcyU5IaLISFO0xZSU5mmEPvdSoDnyAcV8pV44qhLtAvd29n0ehG259oRihtljTWeiu9V60a1N2tbZVl5mEqSK-6_xZvNYA1TCdzNctvweH24unV7U3wer9XA9Q6kvJWDVJ4oKaQsKMrCSMlteBJMRxWbGK7ddUq6F7GdQw-3j2M-qdJvVKm9UPjY9rc1lPgol25-oJxTu7nxGlbJUH-4m5pevAN6NyZ6lfhbjWTKlxkrEKZvQXs_Yf6cpXEwpI_ZJeriq1UC1XHIpRkDwdOY9MH3an4RdDl2r9vGl_IwlKPNdh_5aF3jLgn7PCit1FNJAwC8fIncAXgAlgcXIpRXdfJk4bBiO89GGccSyDh2EgXYdpG3XvNgGWy7npuSoNTE7WIyblAk13UQuO4sdCbMIuriCdyfE73mvwj15xgb07RZRQtFGlFTmnFcIdZ90zDrWXDbANntv7KCKwNvoTuv64bY3HiGbj-NQ-U9eMylWVpvr4hrXcES8c9K3PqHWADZC0iIOvlzFv4VBoc_wVflcOrL_SIoaNFCNBAZZq-2v5lAgpJTqVOtqJ_HVraoSfcKy5g45p-qULunXj6Jwq21fobQiKubBKKOZwcJFyJD7F4ACKXOrz-HIvSHMCWW_9dVrRuCpJw0s0aVFbRqopDNhu446nqb4_EDYQM1tTHMozPd_jKxRRD0sH75X8ZoToxFSpLBDbtdWcenxj-zBf6IGWfZnmaetjKEBYJWC7QDQx1A91pJVJCEgieCkoIfTqkeQuePpIyu48g2FG3P1zjRF-kumhUTfSjo5qS0YiZQy0E1BMs6M11EvuxXRsHClLHoy5nLYI2Sj4zjVjYyxSHyPRPGGo9hwB34yWxzYNtPPGiqXS_dNCpi_zRZwRY4lCGrQ-hYTEWIK1Dm5OlttvC4_eiQ1dv63NiGkLRJ5kJA3bICN0fzCDY-MBqnd1cWn8YVBijVkgtaoascjL9EywDgJdeHnXK0eeOvUxHHhXJVkNqcibn8O4RQdpVU60TSA-uiu675ytIjcBHC6kTv8A8pmkj_4oypPd-F92YIJC741swkYQoeIHj8rE-ThcMUkF7KqC5VORbZTRp8HsZSqgiJcIPaouuxd1-8Rxrid3fXkE6p8bkrysPYoxWEJgh7ZFsRCPDWX-yTeJwFN0PKFP1j0F6YtlLfK5wv-c4F8ZQHA_-yc_gODicy7KmWDZgbTP07e7gEWzw4MFRrndjbDQ',\n  }\n\n  await t.throwsAsync(calculateJwkThumbprint({ ...akp, alg: undefined }), {\n    code: 'ERR_JWK_INVALID',\n    message: '\"alg\" (Algorithm) Parameter missing or invalid',\n  })\n\n  await t.throwsAsync(calculateJwkThumbprint({ ...akp, pub: undefined }), {\n    code: 'ERR_JWK_INVALID',\n    message: '\"pub\" (Public key) Parameter missing or invalid',\n  })\n\n  t.is(await calculateJwkThumbprint(akp), 'T4xl70S7MT6Zeq6r9V9fPJGVn76wfnXJ21-gyo0Gu6o')\n})\n"
  },
  {
    "path": "test/jwks/local.test.ts",
    "content": "import test from 'ava'\n\nimport { createLocalJWKSet } from '../../src/index.js'\n\ntest('LocalJWKSet', async (t) => {\n  for (const f of [\n    null,\n    {},\n    { keys: null },\n    { keys: {} },\n    { keys: [null] },\n    { keys: [0] },\n    { keys: [undefined] },\n    { keys: [[]] },\n    1,\n    Boolean,\n  ]) {\n    t.throws(() => createLocalJWKSet(f), { code: 'ERR_JWKS_INVALID' })\n  }\n\n  const jwks = { keys: [] }\n  const set = createLocalJWKSet(jwks)\n\n  const clone = set.jwks()\n  t.false(clone === jwks)\n  t.false(clone === set.jwks())\n  t.deepEqual(clone, jwks)\n  t.deepEqual(clone, set.jwks())\n})\n"
  },
  {
    "path": "test/jwks/remote.test.ts",
    "content": "import anyTest, { type TestFn } from 'ava'\nimport timekeeper from 'timekeeper'\nimport { createServer } from 'http'\nimport { once } from 'events'\nimport { MockAgent, setGlobalDispatcher } from 'undici'\nimport type { Server } from 'node:net'\n\nconst agent = new MockAgent()\nagent.disableNetConnect()\nsetGlobalDispatcher(agent)\n\nimport {\n  jwtVerify,\n  SignJWT,\n  importJWK,\n  createRemoteJWKSet,\n  errors,\n  FlattenedJWSInput,\n} from '../../src/index.js'\n\nconst now = 1604416038\n\ninterface WithServer {\n  server: Server\n}\n\nconst test = anyTest as TestFn<WithServer>\n\ntest.before(async (t) => {\n  agent.disableNetConnect()\n  t.context.server = createServer().unref().listen(3000)\n  t.context.server.removeAllListeners('request')\n  await once(t.context.server, 'listening')\n})\n\ntest.after(async (t) => {\n  agent.enableNetConnect()\n  await new Promise((resolve) => t.context.server.close(resolve))\n})\n\ntest.afterEach(() => {\n  agent.disableNetConnect()\n})\n\ntest.afterEach((t) => {\n  t.context.server.removeAllListeners('request')\n  agent.assertNoPendingInterceptors()\n})\n\ntest.afterEach(() => timekeeper.reset())\n\ntest.serial('RemoteJWKSet', async (t) => {\n  const keys = [\n    {\n      e: 'AQAB',\n      n: 'wAR7gpvDJx2cUR15R1gyBYxEXanhOIDzk7evzadBpNCEpf6HA6utqMrf8dZ3EXSslKPSPBD5Qrz63kc2u8y7NqzwJQIi_i5xR6AxAyWLG3_kOHBwxnct6talLCZqgr8pDwnyP1BPnIaNf2hZxgS-UZbHCAVycd1n2qCdyb4FzFhcaNtiOLg5VSfgvtOdhHQlDXW-DBvwatpd9HzzTP6l5MZRyQ-N_AoGbIfhNCZRUfnb-A8IBPSqXBWN4TEpt-0yHAOIhWnSpu66AYE4f1efZdHVFCTQZ13e5bS-5RQra4pfmGqU9hog1j1SpHnDTia-s__qGi43rev2MqzY-qeUlw',\n      d: 'buWn14TSLtMhJo_ZLWU4bo_WJCoq0xFWm-eodyOz-9YZ5iycGXibcTLKJ8fvOHuj-KysjNhYvTybvqhuagQR08AJabZUM2zrK6zO4bxbHOS-EAKQf27xbAHPnzIIrb5tnivmZr6hXAsxyXWg84ZlzIVCKdXLhQuUIWZF-u_uNVeJSUTDMRVTL2J0mzAGTXqi-yHejapEeLS7lFXDe6cpDnBVXauJfB4GmSUOjxtdAEVW7uGNQJGarGwRz6l3Tpy_xQiYl8e_IrU1N6qAN_HJEBrdgfK7js93RcsxHGbtdnj1ylevZqGFpB1UXrWE4JSz3sJgyXrmKNFFWOCjalMccQ',\n      p: '98OCXxur1omXdjfWkDubqkI3xRehVQryIhqt0go-1yLS4Nwa7KyrdAbzTo81bCHN0A-NlmIvHA4YZc8QUHftq65s4nCbb3g_CwTfGCJEVCvoaTO2EE6Pd8VrGu2PVsN4SM52Gc0TNJGS54yUhyCWDTi1onUBEg8gnqpMSoWuaVM',\n      q: 'xmaRdSJf4wN5Vse5jiIjZy5jy9veHHhzXxTmW25epr9KTMERUDDCzX0bNbnF8jCvDFN5ebzcEe-9nkWyzJ17wVcJTouEfw8A5pBPcx6Gr8Kd8WIrUjuom4xu-4619kMItoV4j62_nq3p0QUGot_6CgUdq63PCp9Fh-sHv8wViy0',\n      dp: '0OCXwbzfYu_-rCCpGFHYi3Jl-BhS4BJpTc02K3SNw-vM4ttNK6jqptfRObLMNAxPqg_iqxy9YKaVdQdbVqu0yF811rVepVw3sf96YatJ9bhKqJ566EaC91ONV1dd16TVfHPq5xeYEGKF-gXvlfgn6J-dqYeAzovIUVt7E_ydrJc',\n      dq: 'sYDOnqe0dhyDkNp77ugoGIZujtMVcw9o2SaPujmSwUjfprANV1tozgQiNf0RVk-sLTD5u6r2ka2WTmY5Q8uaDy5Zi0ZTsoGv4pg2HN6wzcsnF_EmpRnvDcuk97eEoOD0iKf9Zz6h88vRJ0qB13Lf99r_4rtMQ0qgIKxscHKcy7k',\n      qi: '7uvpgL15VFjd_zjhU0fPVeTzAa6Vg3P3Q2v5DLwLkAIlQDqF50maTYztxtxssVNJtEMIxKefwrmGkyVCXNhrGHZDoj7wj-2o0k878bQqtltCO2TPm9TSYZgW7dR3ji0t4Msc5DcrQL002M_Vxqr9MAunQcAsnulRTepQM2n-aOc',\n      kty: 'RSA',\n      kid: 'ZuLUAgyr6RQV3ERjDukHzOO_90rVbrPiE1vD_HtPFuM',\n    },\n    {\n      e: 'AQAB',\n      n: '0PjQVV2ZAT27Y0h7hfAWWcnPetORCvR1_gHvEUxtlrlnhZia7utHl7BCJH9HP17YHMMBeeEkmUDflYoUL6MDl4DYHgVDq8jZfu1pxH1XqrpeswqOVoReknEe0F5kRt_mPtIoShI2Qv-pxGAw392akAXTirVRLL4Fn_0Oiifxp182P7eTPy41rlKDevLHuKHBZzzaes_33YE2epY2YCLp9k3mZ-tJEei2qiq0T1fERQicGUL8kppOnz0cDNuKRBHyYtXWhjhuDQ8OZQHNLfte9cqzTJMJ4Leu4MGjikSZMsk-_aRFnXtYHH0orwY-giSenRnwNaReAXaR1Px9ReljAQ',\n      d: 'LXGufKH6IBb4pUKh-iKX-ba1dBSGOkenUTHCd5STUG_JX3gsWUC5NPeTqrQzHkjV3otZytN3TgyZkr-QXDurEEtotD6Y1Ma85aljkuNfKTWWWoE1KwNmPZp0BQRB8lfGjmrNcC49tpw6owX4GvbqId_ifQupN32rY3t4qfq9xpO9SAqZF0oUMoS7xE0zChsCJmNYpD9jx87p5Vud1naeaZPlvwWW0ITV4kp2zjYSbBh5DkI52rSrGjkuzlsJ_lKJk5YB557OHhN9XTRBnjqlwwWevh6QAoUivqpcelcplgmfxTHoII1opovYXn8AVt-DbGSO_7LLJ0Sw9sJR5GAqcQ',\n      p: '9RdDqZ3O73lH6nWUGi0abQRRfgvj-HM0zP7GSDQ185l-ZByletl1VuJ86qYJTUY8Q3Gagv6_eXmQMo_14-0wT_FPUMiTMYsjw5QNgFgjlJTM1AayS_U5ddix_Ut7Kti7EXgM0gsavsIazv2-xwCrFzD4sa-t2FWELzzWxgt8wbs',\n      q: '2kX8MN8ItGnn7NnPx-0iqe8kkhy5s9gJRiD3mxN9E6xzRCnf488yhc3aBwI9kZzQtV0XVjX5VhCws5vnJv9b7KA8NATDhpGNrqy2h9ncmsjTTjafUg3jb6QG08kIKDR-A97Mc-MJbIUNzYs10BAG4z9wk7t1bdo4gZJEvjiXVHM',\n      dp: 'Ahggy-I9Um6G3soCafbYsvXGfH09hXH2kYnbx-IqU9qL6e8UuugAyK1Gw_qHOdHP0gO2fkgO-sq_IK96OmhccVJuixIrr9CwjYtGUkJui2Z6GZW1EFEYHJmta6ypcMRJVOzhrynJILgn4nzolGq9C4WvmlUV9zND3eN3MloGxuE',\n      dq: 'uXKWlusX2TjVvM0-FO2r8tdkqeNP_7XAA15FIPOI5Cszb6loOIQ0t6wy3puPteSXClBCYJPQ-MeLab4-wUpaTovBOq0FdpK53ruNBZUbMkMIDL6p1CxKnPKufkeh747RtfYYnSk7O4E8PfNV0CWdxHuE6W9ukNvEAIpGb5tjL3M',\n      qi: '3BLQ03cHEmO8nUT7U8M_H_JciEWAH8XWh_9nihIhXzLKYbNmWM16Ah0F9DUg0GPeiG7e_08ZJ4X3oK1bHnnXdns6NSOEoULWfHl5LUY5PoFPYaBDy3f6td2SCTE83p1YzegXKysWEk1snA2ROq4UEfz1vL8v64RtwR3SvNrAyOI',\n      kty: 'RSA',\n      alg: 'RS256',\n      kid: 'hJU8GvYjtifxLVuBDSNmhLBF19wQHaZvQhfpT3wKzpE',\n    },\n    {\n      crv: 'P-256',\n      x: 'fqCXPnWs3sSfwztvwYU9SthmRdoT4WCXxS8eD8icF6U',\n      y: 'nP6GIc42c61hoKqPcZqkvzhzIJkBV3Jw3g8sGG7UeP8',\n      d: 'XikZvoy8ayRpOnuz7ont2DkgMxp_kmmg1EKcuIJWX_E',\n      kty: 'EC',\n      kid: 'a-5xuiQoRqlLBtec9jRpXoGTVOP10SGnj2Und0CHHxw',\n    },\n  ]\n  const jwks = {\n    keys: [\n      {\n        e: 'AQAB',\n        n: 'wAR7gpvDJx2cUR15R1gyBYxEXanhOIDzk7evzadBpNCEpf6HA6utqMrf8dZ3EXSslKPSPBD5Qrz63kc2u8y7NqzwJQIi_i5xR6AxAyWLG3_kOHBwxnct6talLCZqgr8pDwnyP1BPnIaNf2hZxgS-UZbHCAVycd1n2qCdyb4FzFhcaNtiOLg5VSfgvtOdhHQlDXW-DBvwatpd9HzzTP6l5MZRyQ-N_AoGbIfhNCZRUfnb-A8IBPSqXBWN4TEpt-0yHAOIhWnSpu66AYE4f1efZdHVFCTQZ13e5bS-5RQra4pfmGqU9hog1j1SpHnDTia-s__qGi43rev2MqzY-qeUlw',\n        kty: 'RSA',\n        kid: 'ZuLUAgyr6RQV3ERjDukHzOO_90rVbrPiE1vD_HtPFuM',\n      },\n      {\n        e: 'AQAB',\n        n: '0PjQVV2ZAT27Y0h7hfAWWcnPetORCvR1_gHvEUxtlrlnhZia7utHl7BCJH9HP17YHMMBeeEkmUDflYoUL6MDl4DYHgVDq8jZfu1pxH1XqrpeswqOVoReknEe0F5kRt_mPtIoShI2Qv-pxGAw392akAXTirVRLL4Fn_0Oiifxp182P7eTPy41rlKDevLHuKHBZzzaes_33YE2epY2YCLp9k3mZ-tJEei2qiq0T1fERQicGUL8kppOnz0cDNuKRBHyYtXWhjhuDQ8OZQHNLfte9cqzTJMJ4Leu4MGjikSZMsk-_aRFnXtYHH0orwY-giSenRnwNaReAXaR1Px9ReljAQ',\n        alg: 'RS256',\n        kty: 'RSA',\n        kid: 'hJU8GvYjtifxLVuBDSNmhLBF19wQHaZvQhfpT3wKzpE',\n      },\n      {\n        crv: 'P-256',\n        x: 'fqCXPnWs3sSfwztvwYU9SthmRdoT4WCXxS8eD8icF6U',\n        y: 'nP6GIc42c61hoKqPcZqkvzhzIJkBV3Jw3g8sGG7UeP8',\n        kty: 'EC',\n        kid: 'a-5xuiQoRqlLBtec9jRpXoGTVOP10SGnj2Und0CHHxw',\n      },\n      {\n        e: 'AQAB',\n        n: '0PjQVV2ZAT27Y0h7hfAWWcnPetORCvR1_gHvEUxtlrlnhZia7utHl7BCJH9HP17YHMMBeeEkmUDflYoUL6MDl4DYHgVDq8jZfu1pxH1XqrpeswqOVoReknEe0F5kRt_mPtIoShI2Qv-pxGAw392akAXTirVRLL4Fn_0Oiifxp182P7eTPy41rlKDevLHuKHBZzzaes_33YE2epY2YCLp9k3mZ-tJEei2qiq0T1fERQicGUL8kppOnz0cDNuKRBHyYtXWhjhuDQ8OZQHNLfte9cqzTJMJ4Leu4MGjikSZMsk-_aRFnXtYHH0orwY-giSenRnwNaReAXaR1Px9ReljAQ',\n        alg: 'RS256',\n        kty: 'RSA',\n        use: 'enc',\n      },\n      {\n        e: 'AQAB',\n        n: '0PjQVV2ZAT27Y0h7hfAWWcnPetORCvR1_gHvEUxtlrlnhZia7utHl7BCJH9HP17YHMMBeeEkmUDflYoUL6MDl4DYHgVDq8jZfu1pxH1XqrpeswqOVoReknEe0F5kRt_mPtIoShI2Qv-pxGAw392akAXTirVRLL4Fn_0Oiifxp182P7eTPy41rlKDevLHuKHBZzzaes_33YE2epY2YCLp9k3mZ-tJEei2qiq0T1fERQicGUL8kppOnz0cDNuKRBHyYtXWhjhuDQ8OZQHNLfte9cqzTJMJ4Leu4MGjikSZMsk-_aRFnXtYHH0orwY-giSenRnwNaReAXaR1Px9ReljAQ',\n        alg: 'RS256',\n        kty: 'RSA',\n        use: 'sig',\n        key_ops: [],\n      },\n    ],\n  }\n\n  agent\n    .get('https://as.example.com')\n    .intercept({\n      path: '/jwks',\n      headers(headers) {\n        return !!headers['user-agent'].match(/jose\\/v\\d+\\.\\d+\\.\\d+/)\n      },\n    })\n    .reply(200, jwks)\n\n  const url = new URL('https://as.example.com/jwks')\n  const JWKS = createRemoteJWKSet(url)\n  // Signed JWT\n  {\n    const [jwk] = keys\n    const key = await importJWK({ ...jwk, alg: 'PS256' })\n    const jwt = await new SignJWT().setProtectedHeader({ alg: 'PS256', kid: jwk.kid }).sign(key)\n    await t.notThrowsAsync(async () => {\n      const { key: resolvedKey } = await jwtVerify(jwt, JWKS)\n      t.truthy(resolvedKey)\n      t.true(resolvedKey instanceof CryptoKey)\n      t.is((resolvedKey as CryptoKey).type, 'public')\n    })\n  }\n  {\n    const [jwk] = keys\n    const key = await importJWK({ ...jwk, alg: 'RS256' })\n    const jwt = await new SignJWT().setProtectedHeader({ alg: 'RS256' }).sign(key)\n    let error: errors.JWKSMultipleMatchingKeys = await t.throwsAsync(jwtVerify(jwt, JWKS), {\n      code: 'ERR_JWKS_MULTIPLE_MATCHING_KEYS',\n      message: 'multiple matching keys found in the JSON Web Key Set',\n    })\n\n    // async iterator (KeyLike)\n    {\n      const cache = new WeakSet()\n      for await (const ko of error) {\n        t.like(ko, { type: 'public' })\n        cache.add(ko)\n      }\n      error = await t.throwsAsync(jwtVerify(jwt, JWKS), {\n        code: 'ERR_JWKS_MULTIPLE_MATCHING_KEYS',\n        message: 'multiple matching keys found in the JSON Web Key Set',\n      })\n      let i = 0\n      for await (const ko of error) {\n        i++\n        t.true(cache.has(ko))\n      }\n      t.is(i, 2)\n    }\n  }\n  {\n    const [, jwk] = keys\n    const key = await importJWK({ ...jwk, alg: 'PS256' })\n    const jwt = await new SignJWT().setProtectedHeader({ alg: 'PS256', kid: jwk.kid }).sign(key)\n    await t.throwsAsync(jwtVerify(jwt, JWKS), {\n      code: 'ERR_JWKS_NO_MATCHING_KEY',\n      message: 'no applicable key found in the JSON Web Key Set',\n    })\n  }\n  {\n    const [, , jwk] = keys\n    const key = await importJWK({ ...jwk, alg: 'ES256' })\n    const jwt = await new SignJWT().setProtectedHeader({ alg: 'ES256' }).sign(key)\n    await t.notThrowsAsync(jwtVerify(jwt, JWKS))\n  }\n})\n\ntest.serial('refreshes the JWKS once off cooldown', async (t) => {\n  timekeeper.freeze(now * 1000)\n  const jwk = {\n    crv: 'P-256',\n    x: 'fqCXPnWs3sSfwztvwYU9SthmRdoT4WCXxS8eD8icF6U',\n    y: 'nP6GIc42c61hoKqPcZqkvzhzIJkBV3Jw3g8sGG7UeP8',\n    d: 'XikZvoy8ayRpOnuz7ont2DkgMxp_kmmg1EKcuIJWX_E',\n    kty: 'EC',\n  }\n  const jwks = {\n    keys: [\n      {\n        crv: 'P-256',\n        x: 'fqCXPnWs3sSfwztvwYU9SthmRdoT4WCXxS8eD8icF6U',\n        y: 'nP6GIc42c61hoKqPcZqkvzhzIJkBV3Jw3g8sGG7UeP8',\n        kty: 'EC',\n        kid: 'one',\n      },\n    ],\n  }\n  const mockAgent = agent.get('https://as.example.com')\n\n  mockAgent.intercept({ path: '/jwks' }).reply(200, jwks)\n\n  const url = new URL('https://as.example.com/jwks')\n  const JWKS = createRemoteJWKSet(url)\n  const key = await importJWK({ ...jwk, alg: 'ES256' })\n  {\n    const jwt = await new SignJWT().setProtectedHeader({ alg: 'ES256', kid: 'one' }).sign(key)\n    await t.notThrowsAsync(jwtVerify(jwt, JWKS))\n    await t.notThrowsAsync(jwtVerify(jwt, JWKS))\n  }\n  {\n    const jwt = await new SignJWT().setProtectedHeader({ alg: 'ES256', kid: 'two' }).sign(key)\n    await t.throwsAsync(jwtVerify(jwt, JWKS), {\n      code: 'ERR_JWKS_NO_MATCHING_KEY',\n      message: 'no applicable key found in the JSON Web Key Set',\n    })\n    jwks.keys[0].kid = 'two'\n    mockAgent.intercept({ path: '/jwks' }).reply(200, jwks)\n    timekeeper.travel((now + 30) * 1000)\n    await t.notThrowsAsync(jwtVerify(jwt, JWKS))\n  }\n})\n\ntest.serial('createRemoteJWKSet manual reload', async (t) => {\n  timekeeper.freeze(now * 1000)\n  const jwk = {\n    crv: 'P-256',\n    x: 'fqCXPnWs3sSfwztvwYU9SthmRdoT4WCXxS8eD8icF6U',\n    y: 'nP6GIc42c61hoKqPcZqkvzhzIJkBV3Jw3g8sGG7UeP8',\n    d: 'XikZvoy8ayRpOnuz7ont2DkgMxp_kmmg1EKcuIJWX_E',\n    kty: 'EC',\n  }\n  const jwks = {\n    keys: [\n      {\n        crv: 'P-256',\n        x: 'fqCXPnWs3sSfwztvwYU9SthmRdoT4WCXxS8eD8icF6U',\n        y: 'nP6GIc42c61hoKqPcZqkvzhzIJkBV3Jw3g8sGG7UeP8',\n        kty: 'EC',\n        kid: 'one',\n      },\n    ],\n  }\n\n  const mockAgent = agent.get('https://as.example.com')\n\n  mockAgent.intercept({ path: '/jwks' }).reply(200, jwks)\n\n  const url = new URL('https://as.example.com/jwks')\n  const JWKS = createRemoteJWKSet(url)\n  t.false(JWKS.coolingDown)\n  t.false(JWKS.fresh)\n  t.false(JWKS.reloading)\n  t.is(JWKS.jwks(), undefined)\n  const key = await importJWK({ ...jwk, alg: 'ES256' })\n  {\n    const jwt = await new SignJWT().setProtectedHeader({ alg: 'ES256', kid: 'two' }).sign(key)\n    await t.throwsAsync(jwtVerify(jwt, JWKS), {\n      code: 'ERR_JWKS_NO_MATCHING_KEY',\n      message: 'no applicable key found in the JSON Web Key Set',\n    })\n    jwks.keys[0].kid = 'two'\n    mockAgent.intercept({ path: '/jwks' }).reply(200, jwks)\n    t.true(JWKS.coolingDown)\n    t.true(JWKS.fresh)\n    t.false(JWKS.reloading)\n    t.notDeepEqual(JWKS.jwks(), jwks)\n    const reload = JWKS.reload()\n    t.true(JWKS.reloading)\n    await reload\n    t.true(JWKS.coolingDown)\n    t.true(JWKS.fresh)\n    t.false(JWKS.reloading)\n    t.deepEqual(JWKS.jwks(), jwks)\n    await t.notThrowsAsync(jwtVerify(jwt, JWKS))\n    JWKS.jwks()!.keys = []\n    t.deepEqual(JWKS.jwks(), jwks)\n    await t.notThrowsAsync(jwtVerify(jwt, JWKS))\n  }\n})\n\ntest.serial('refreshes the JWKS once stale', async (t) => {\n  timekeeper.freeze(now * 1000)\n  const jwk = {\n    crv: 'P-256',\n    x: 'fqCXPnWs3sSfwztvwYU9SthmRdoT4WCXxS8eD8icF6U',\n    y: 'nP6GIc42c61hoKqPcZqkvzhzIJkBV3Jw3g8sGG7UeP8',\n    d: 'XikZvoy8ayRpOnuz7ont2DkgMxp_kmmg1EKcuIJWX_E',\n    kty: 'EC',\n  }\n  const jwks = {\n    keys: [\n      {\n        crv: 'P-256',\n        x: 'fqCXPnWs3sSfwztvwYU9SthmRdoT4WCXxS8eD8icF6U',\n        y: 'nP6GIc42c61hoKqPcZqkvzhzIJkBV3Jw3g8sGG7UeP8',\n        kty: 'EC',\n        kid: 'one',\n      },\n    ],\n  }\n\n  agent.get('https://as.example.com').intercept({ path: '/jwks' }).reply(200, jwks).times(2)\n\n  const url = new URL('https://as.example.com/jwks')\n  const JWKS = createRemoteJWKSet(url, { cacheMaxAge: 60 * 10 * 1000 })\n  const key = await importJWK({ ...jwk, alg: 'ES256' })\n  {\n    const jwt = await new SignJWT().setProtectedHeader({ alg: 'ES256', kid: 'one' }).sign(key)\n    await t.notThrowsAsync(jwtVerify(jwt, JWKS))\n    await t.notThrowsAsync(jwtVerify(jwt, JWKS))\n    timekeeper.travel((now + 60 * 10) * 1000)\n    await t.notThrowsAsync(jwtVerify(jwt, JWKS))\n  }\n})\n\ntest.serial('can be configured to never be stale', async (t) => {\n  timekeeper.freeze(now * 1000)\n  const jwk = {\n    crv: 'P-256',\n    x: 'fqCXPnWs3sSfwztvwYU9SthmRdoT4WCXxS8eD8icF6U',\n    y: 'nP6GIc42c61hoKqPcZqkvzhzIJkBV3Jw3g8sGG7UeP8',\n    d: 'XikZvoy8ayRpOnuz7ont2DkgMxp_kmmg1EKcuIJWX_E',\n    kty: 'EC',\n  }\n  const jwks = {\n    keys: [\n      {\n        crv: 'P-256',\n        x: 'fqCXPnWs3sSfwztvwYU9SthmRdoT4WCXxS8eD8icF6U',\n        y: 'nP6GIc42c61hoKqPcZqkvzhzIJkBV3Jw3g8sGG7UeP8',\n        kty: 'EC',\n        kid: 'one',\n      },\n    ],\n  }\n\n  agent.get('https://as.example.com').intercept({ path: '/jwks' }).reply(200, jwks)\n\n  const url = new URL('https://as.example.com/jwks')\n  const JWKS = createRemoteJWKSet(url, { cacheMaxAge: Infinity })\n  const key = await importJWK({ ...jwk, alg: 'ES256' })\n  {\n    const jwt = await new SignJWT().setProtectedHeader({ alg: 'ES256', kid: 'one' }).sign(key)\n    await t.notThrowsAsync(jwtVerify(jwt, JWKS))\n    await t.notThrowsAsync(jwtVerify(jwt, JWKS))\n    timekeeper.travel((now + 60 * 10) * 1000)\n    await t.notThrowsAsync(jwtVerify(jwt, JWKS))\n  }\n})\n\ntest.serial('throws on invalid JWKSet', async (t) => {\n  const mockAgent = agent.get('https://as.example.com')\n\n  mockAgent.intercept({ path: '/jwks' }).reply(200, 'null')\n  const url = new URL('https://as.example.com/jwks')\n  const JWKS = createRemoteJWKSet(url)\n  await t.throwsAsync(JWKS({ alg: 'RS256' }, {} as FlattenedJWSInput), {\n    code: 'ERR_JWKS_INVALID',\n    message: 'JSON Web Key Set malformed',\n  })\n\n  mockAgent.intercept({ path: '/jwks' }).reply(200, {})\n  await t.throwsAsync(JWKS({ alg: 'RS256' }, {} as FlattenedJWSInput), {\n    code: 'ERR_JWKS_INVALID',\n    message: 'JSON Web Key Set malformed',\n  })\n\n  mockAgent.intercept({ path: '/jwks' }).reply(200, { keys: null })\n  await t.throwsAsync(JWKS({ alg: 'RS256' }, {} as FlattenedJWSInput), {\n    code: 'ERR_JWKS_INVALID',\n    message: 'JSON Web Key Set malformed',\n  })\n\n  mockAgent\n    .intercept({ path: '/jwks' })\n\n    .reply(200, { keys: [null] })\n  await t.throwsAsync(JWKS({ alg: 'RS256' }, {} as FlattenedJWSInput), {\n    code: 'ERR_JWKS_INVALID',\n    message: 'JSON Web Key Set malformed',\n  })\n\n  mockAgent.intercept({ path: '/jwks' }).reply(404)\n  await t.throwsAsync(JWKS({ alg: 'RS256' }, {} as FlattenedJWSInput), {\n    code: 'ERR_JOSE_GENERIC',\n    message: 'Expected 200 OK from the JSON Web Key Set HTTP response',\n  })\n\n  mockAgent.intercept({ path: '/jwks' }).reply(200, '{')\n  await t.throwsAsync(JWKS({ alg: 'RS256' }, {} as FlattenedJWSInput), {\n    code: 'ERR_JOSE_GENERIC',\n    message: 'Failed to parse the JSON Web Key Set HTTP response as JSON',\n  })\n})\n\ntest.serial('can have headers configured', async (t) => {\n  agent\n    .get('https://as.example.com')\n    .intercept({\n      path: '/jwks',\n      headers: {\n        'x-custom': 'foo',\n      },\n    })\n    .reply(200, 'null')\n\n  const url = new URL('https://as.example.com/jwks')\n  const JWKS = createRemoteJWKSet(url, { headers: { 'x-custom': 'foo' } })\n  await JWKS().catch(() => {})\n  t.pass()\n})\n\ntest('handles ENOTFOUND', async (t) => {\n  agent.enableNetConnect()\n  const url = new URL('https://op.example.com/jwks')\n  const JWKS = createRemoteJWKSet(url)\n  const err = await t.throwsAsync(JWKS({ alg: 'RS256' }, {} as FlattenedJWSInput))\n  t.true(err instanceof Error)\n  t.true(err.cause instanceof Error && 'code' in err.cause && err.cause.code === 'ENOTFOUND')\n})\n\ntest('handles ECONNREFUSED', async (t) => {\n  agent.enableNetConnect()\n  const url = new URL('http://localhost:3001/jwks')\n  const JWKS = createRemoteJWKSet(url)\n  const err = await t.throwsAsync(JWKS({ alg: 'RS256' }, {} as FlattenedJWSInput))\n  t.true(err instanceof Error)\n  t.true(err.cause instanceof Error && 'code' in err.cause && err.cause.code === 'ECONNREFUSED')\n})\n\ntest.serial('handles a timeout', async (t) => {\n  t.timeout(1000)\n  agent.enableNetConnect()\n  const url = new URL('http://localhost:3000/jwks')\n  const JWKS = createRemoteJWKSet(url, {\n    timeoutDuration: 500,\n  })\n  const err = await t.throwsAsync(JWKS({ alg: 'RS256' }, {} as FlattenedJWSInput))\n  t.true(err instanceof errors.JWKSTimeout)\n})\n"
  },
  {
    "path": "test/jws/compact.sign.test.ts",
    "content": "import test from 'ava'\n\nimport { CompactSign } from '../../src/index.js'\n\ntest.before((t) => {\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n  t.context.payload = encode('It’s a dangerous business, Frodo, going out your door.')\n  t.context.secret = new Uint8Array(32)\n})\n\ntest('CompactSign', async (t) => {\n  const jws = await new CompactSign(t.context.payload)\n    .setProtectedHeader({ alg: 'HS256' })\n    .sign(t.context.secret)\n  t.is(\n    jws,\n    'eyJhbGciOiJIUzI1NiJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4.UKohvCM6JaKEJlDt7ApBPgcQMW4lmp-UGXfwPmCfUaA',\n  )\n})\n\ntest('CompactSign.prototype.setProtectedHeader', (t) => {\n  t.throws(() => new CompactSign(t.context.payload).setProtectedHeader({}).setProtectedHeader({}), {\n    instanceOf: TypeError,\n    message: 'setProtectedHeader can only be called once',\n  })\n})\n\ntest('CompactSign.prototype.sign must have a JOSE header', async (t) => {\n  await t.throwsAsync(new CompactSign(t.context.payload).sign(t.context.secret), {\n    code: 'ERR_JWS_INVALID',\n    message: 'either setProtectedHeader or setUnprotectedHeader must be called before #sign()',\n  })\n})\n\ntest('CompactSign.prototype.sign JOSE header have an alg', async (t) => {\n  await t.throwsAsync(\n    new CompactSign(t.context.payload).setProtectedHeader({}).sign(t.context.secret),\n    {\n      code: 'ERR_JWS_INVALID',\n      message: 'JWS \"alg\" (Algorithm) Header Parameter missing or invalid',\n    },\n  )\n})\n"
  },
  {
    "path": "test/jws/compact.verify.test.ts",
    "content": "import test from 'ava'\nimport * as crypto from 'crypto'\n\nimport { compactVerify, CompactSign } from '../../src/index.js'\n\ntest.before(async (t) => {\n  t.context.secret = crypto.randomFillSync(new Uint8Array(32))\n})\n\ntest('JWS format validation', async (t) => {\n  {\n    await t.notThrowsAsync(async () => {\n      await compactVerify(\n        await new CompactSign(new Uint8Array())\n          .setProtectedHeader({ alg: 'HS256' })\n          .sign(t.context.secret),\n        t.context.secret,\n      )\n    })\n  }\n\n  await t.throwsAsync(compactVerify(null, new Uint8Array(0)), {\n    message: 'Compact JWS must be a string or Uint8Array',\n    code: 'ERR_JWS_INVALID',\n  })\n  await t.throwsAsync(compactVerify('.....', new Uint8Array(0)), {\n    message: 'Invalid Compact JWS',\n    code: 'ERR_JWS_INVALID',\n  })\n})\n\ntest('sign empty data', async (t) => {\n  const jws = await new CompactSign(new Uint8Array(0))\n    .setProtectedHeader({ alg: 'HS256' })\n    .sign(new Uint8Array(32))\n\n  t.is(jws.split('.')[1], '')\n\n  const { payload } = await compactVerify(jws, new Uint8Array(32))\n  t.is(payload.byteLength, 0)\n})\n"
  },
  {
    "path": "test/jws/crit.test.ts",
    "content": "import test from 'ava'\n\nimport { FlattenedSign } from '../../src/index.js'\n\nconst encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n\ntest('crit member checks check', async (t) => {\n  await t.throwsAsync(\n    new FlattenedSign(encode('foo'))\n      .setProtectedHeader({ alg: 'HS256' })\n      .setUnprotectedHeader({ crit: ['b64'] })\n      .sign(new Uint8Array(32)),\n    {\n      code: 'ERR_JWS_INVALID',\n      message: '\"crit\" (Critical) Header Parameter MUST be integrity protected',\n    },\n  )\n  await t.throwsAsync(\n    new FlattenedSign(encode('foo'))\n      .setProtectedHeader({ alg: 'HS256', crit: [null], b64: false })\n      .sign(new Uint8Array(32)),\n    {\n      code: 'ERR_JWS_INVALID',\n      message:\n        '\"crit\" (Critical) Header Parameter MUST be an array of non-empty strings when present',\n    },\n  )\n  await t.throwsAsync(\n    new FlattenedSign(encode('foo'))\n      .setProtectedHeader({ alg: 'HS256', crit: ['nope'], nope: 'foo' })\n      .sign(new Uint8Array(32)),\n    {\n      code: 'ERR_JOSE_NOT_SUPPORTED',\n      message: 'Extension Header Parameter \"nope\" is not recognized',\n    },\n  )\n})\n"
  },
  {
    "path": "test/jws/flattened.sign.test.ts",
    "content": "import test from 'ava'\n\nimport { FlattenedSign } from '../../src/index.js'\n\ntest.before(async (t) => {\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n  t.context.payload = encode('It’s a dangerous business, Frodo, going out your door.')\n  t.context.secret = new Uint8Array(32)\n})\n\ntest('FlattenedSign', async (t) => {\n  {\n    const jws = await new FlattenedSign(t.context.payload)\n      .setProtectedHeader({ alg: 'HS256' })\n      .setUnprotectedHeader({ foo: 'bar' })\n      .sign(t.context.secret)\n    t.deepEqual(jws, {\n      header: {\n        foo: 'bar',\n      },\n      payload: 'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',\n      protected: 'eyJhbGciOiJIUzI1NiJ9',\n      signature: 'UKohvCM6JaKEJlDt7ApBPgcQMW4lmp-UGXfwPmCfUaA',\n    })\n  }\n  {\n    const jws = await new FlattenedSign(t.context.payload)\n      .setProtectedHeader({ alg: 'HS256' })\n      .sign(t.context.secret)\n    t.deepEqual(jws, {\n      protected: 'eyJhbGciOiJIUzI1NiJ9',\n      payload: 'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',\n      signature: 'UKohvCM6JaKEJlDt7ApBPgcQMW4lmp-UGXfwPmCfUaA',\n    })\n  }\n  {\n    const jws = await new FlattenedSign(t.context.payload)\n      .setUnprotectedHeader({ alg: 'HS256' })\n      .sign(t.context.secret)\n    t.deepEqual(jws, {\n      header: {\n        alg: 'HS256',\n      },\n      payload: 'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',\n      signature: 'O7HdMZ_6_aEQWLGGItmCKN3pf8-nZ9mHnPfT7rrPCwk',\n    })\n  }\n  {\n    for (const value of [\n      undefined,\n      null,\n      {},\n      '',\n      'foo',\n      1,\n      0,\n      true,\n      false,\n      [],\n      new FlattenedSign(new Uint8Array()),\n    ]) {\n      t.throws(() => new FlattenedSign(value), {\n        instanceOf: TypeError,\n        message: 'payload must be an instance of Uint8Array',\n      })\n    }\n  }\n})\n\ntest('FlattenedSign.prototype.setProtectedHeader', (t) => {\n  t.throws(\n    () => new FlattenedSign(t.context.payload).setProtectedHeader({}).setProtectedHeader({}),\n    {\n      instanceOf: TypeError,\n      message: 'setProtectedHeader can only be called once',\n    },\n  )\n})\n\ntest('FlattenedSign.prototype.setUnprotectedHeader', (t) => {\n  t.throws(\n    () => new FlattenedSign(t.context.payload).setUnprotectedHeader({}).setUnprotectedHeader({}),\n    {\n      instanceOf: TypeError,\n      message: 'setUnprotectedHeader can only be called once',\n    },\n  )\n})\n\ntest('FlattenedSign.prototype.sign must have a JOSE header', async (t) => {\n  await t.throwsAsync(new FlattenedSign(t.context.payload).sign(t.context.secret), {\n    code: 'ERR_JWS_INVALID',\n    message: 'either setProtectedHeader or setUnprotectedHeader must be called before #sign()',\n  })\n})\n\ntest('FlattenedSign.prototype.sign JOSE header must be disjoint', async (t) => {\n  await t.throwsAsync(\n    new FlattenedSign(t.context.payload)\n      .setProtectedHeader({ alg: 'HS256' })\n      .setUnprotectedHeader({ alg: 'HS256' })\n      .sign(t.context.secret),\n    {\n      code: 'ERR_JWS_INVALID',\n      message: 'JWS Protected and JWS Unprotected Header Parameter names must be disjoint',\n    },\n  )\n})\n\ntest('FlattenedSign.prototype.sign JOSE header have an alg', async (t) => {\n  await t.throwsAsync(\n    new FlattenedSign(t.context.payload)\n      .setProtectedHeader({})\n      .setUnprotectedHeader({})\n      .sign(t.context.secret),\n    {\n      code: 'ERR_JWS_INVALID',\n      message: 'JWS \"alg\" (Algorithm) Header Parameter missing or invalid',\n    },\n  )\n  await t.notThrowsAsync(\n    new FlattenedSign(t.context.payload)\n      .setProtectedHeader({ alg: 'HS256' })\n      .setUnprotectedHeader({ foo: 'bar' })\n      .sign(t.context.secret),\n  )\n  await t.notThrowsAsync(\n    new FlattenedSign(t.context.payload)\n      .setProtectedHeader({ alg: 'HS256' })\n      .sign(t.context.secret),\n  )\n  await t.notThrowsAsync(\n    new FlattenedSign(t.context.payload)\n      .setProtectedHeader({ foo: 'bar' })\n      .setUnprotectedHeader({ alg: 'HS256' })\n      .sign(t.context.secret),\n  )\n  await t.notThrowsAsync(\n    new FlattenedSign(t.context.payload)\n      .setUnprotectedHeader({ alg: 'HS256' })\n      .sign(t.context.secret),\n  )\n})\n"
  },
  {
    "path": "test/jws/flattened.verify.test.ts",
    "content": "import test from 'ava'\nimport * as crypto from 'crypto'\n\nimport { FlattenedSign, flattenedVerify } from '../../src/index.js'\n\ntest.before(async (t) => {\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n  t.context.plaintext = encode('It’s a dangerous business, Frodo, going out your door.')\n  t.context.secret = crypto.randomFillSync(new Uint8Array(32))\n})\n\ntest('JWS format validation', async (t) => {\n  const fullJws = await new FlattenedSign(t.context.plaintext)\n    .setProtectedHeader({ bar: 'baz' })\n    .setUnprotectedHeader({ alg: 'HS256' })\n    .sign(t.context.secret)\n\n  {\n    await t.throwsAsync(flattenedVerify(null, t.context.secret), {\n      message: 'Flattened JWS must be an object',\n      code: 'ERR_JWS_INVALID',\n    })\n  }\n\n  {\n    const jws = { ...fullJws }\n    jws.protected = undefined\n    jws.header = undefined\n\n    await t.throwsAsync(flattenedVerify(jws, t.context.secret), {\n      message: 'Flattened JWS must have either of the \"protected\" or \"header\" members',\n      code: 'ERR_JWS_INVALID',\n    })\n  }\n\n  {\n    await t.notThrowsAsync(async () => {\n      await flattenedVerify(\n        await new FlattenedSign(new Uint8Array())\n          .setProtectedHeader({ alg: 'HS256' })\n          .sign(t.context.secret),\n        t.context.secret,\n      )\n    })\n  }\n\n  {\n    const jws = { ...fullJws }\n    jws.signature = undefined\n    const assertion = {\n      message: 'JWS Signature missing or incorrect type',\n      code: 'ERR_JWS_INVALID',\n    }\n\n    await t.throwsAsync(flattenedVerify(jws, t.context.secret), assertion)\n    jws.signature = null\n\n    await t.throwsAsync(flattenedVerify(jws, t.context.secret), assertion)\n  }\n\n  {\n    const jws = { ...fullJws }\n    const assertion = {\n      message: 'JWS Protected Header incorrect type',\n      code: 'ERR_JWS_INVALID',\n    }\n    jws.protected = null\n    await t.throwsAsync(flattenedVerify(jws, t.context.secret), assertion)\n  }\n\n  {\n    const jws = { ...fullJws }\n    const assertion = {\n      message: 'JWS Unprotected Header incorrect type',\n      code: 'ERR_JWS_INVALID',\n    }\n    jws.header = null\n    await t.throwsAsync(flattenedVerify(jws, t.context.secret), assertion)\n  }\n\n  {\n    const jws = { ...fullJws }\n    const assertion = {\n      message: 'JWS Protected Header is invalid',\n      code: 'ERR_JWS_INVALID',\n    }\n    jws.protected = `1${jws.protected}`\n    await t.throwsAsync(flattenedVerify(jws, t.context.secret), assertion)\n  }\n\n  {\n    const jws = { ...fullJws }\n    const assertion = {\n      message: 'JWS Payload missing',\n      code: 'ERR_JWS_INVALID',\n    }\n    jws.payload = undefined\n    await t.throwsAsync(flattenedVerify(jws, t.context.secret), assertion)\n  }\n\n  {\n    const jws = { ...fullJws }\n    jws.header = { alg: 'HS256', bar: 'bar' }\n    const assertion = {\n      message: 'JWS Protected and JWS Unprotected Header Parameter names must be disjoint',\n      code: 'ERR_JWS_INVALID',\n    }\n    await t.throwsAsync(flattenedVerify(jws, t.context.secret), assertion)\n  }\n\n  {\n    const jws = { ...fullJws }\n    jws.header = undefined\n    const assertion = {\n      message: 'JWS \"alg\" (Algorithm) Header Parameter missing or invalid',\n      code: 'ERR_JWS_INVALID',\n    }\n    await t.throwsAsync(flattenedVerify(jws, t.context.secret), assertion)\n  }\n\n  {\n    const jws = { ...fullJws }\n    jws.payload = null\n    const assertion = {\n      message: 'JWS Payload must be a string',\n      code: 'ERR_JWS_INVALID',\n    }\n    await t.throwsAsync(flattenedVerify(jws, t.context.secret), assertion)\n  }\n\n  {\n    const jws = { ...fullJws }\n    const assertion = {\n      message: 'signature verification failed',\n      code: 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED',\n    }\n    await t.throwsAsync(flattenedVerify(jws, crypto.randomFillSync(new Uint8Array(32))), assertion)\n  }\n})\n\ntest('sign empty data', async (t) => {\n  const jws = await new FlattenedSign(new Uint8Array(0))\n    .setProtectedHeader({ alg: 'HS256' })\n    .sign(new Uint8Array(32))\n\n  t.is(jws.payload, '')\n\n  const { payload } = await flattenedVerify(jws, new Uint8Array(32))\n  t.is(payload.byteLength, 0)\n})\n"
  },
  {
    "path": "test/jws/general.test.ts",
    "content": "import test from 'ava'\nimport * as crypto from 'crypto'\n\nimport { GeneralSign, generalVerify } from '../../src/index.js'\n\ntest.before(async (t) => {\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n  t.context.plaintext = encode('It’s a dangerous business, Frodo, going out your door.')\n  t.context.secret = crypto.randomFillSync(new Uint8Array(48))\n})\n\ntest('General JWS signing', async (t) => {\n  const generalJws = await new GeneralSign(t.context.plaintext)\n    .addSignature(t.context.secret)\n    .setProtectedHeader({ bar: 'baz' })\n    .setUnprotectedHeader({ alg: 'HS256' })\n    .addSignature(t.context.secret)\n    .setProtectedHeader({ bar: 'baz' })\n    .setUnprotectedHeader({ alg: 'HS384' })\n    .sign()\n\n  t.is(\n    generalJws.payload,\n    'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',\n  )\n  t.is(generalJws.signatures.length, 2)\n})\n\ntest('General JWS signing b64:false', async (t) => {\n  const generalJws = await new GeneralSign(t.context.plaintext)\n    .addSignature(t.context.secret)\n    .setProtectedHeader({ bar: 'baz', b64: false, crit: ['b64'] })\n    .setUnprotectedHeader({ alg: 'HS256' })\n    .addSignature(t.context.secret)\n    .setProtectedHeader({ bar: 'baz', b64: false, crit: ['b64'] })\n    .setUnprotectedHeader({ alg: 'HS384' })\n    .sign()\n\n  t.is(generalJws.payload, '')\n  t.is(generalJws.signatures.length, 2)\n})\n\ntest('General JWS signing validations', async (t) => {\n  const sig = new GeneralSign(t.context.plaintext)\n\n  t.throws(\n    () => {\n      sig\n        .addSignature(t.context.secret)\n        .setProtectedHeader({ bar: 'baz', crit: ['b64'], b64: false, alg: 'HS256' })\n        .setProtectedHeader({ bar: 'baz', crit: ['b64'], b64: false, alg: 'HS256' })\n    },\n    { instanceOf: TypeError, message: 'setProtectedHeader can only be called once' },\n  )\n\n  t.throws(\n    () => {\n      sig\n        .addSignature(t.context.secret)\n        .setProtectedHeader({ bar: 'baz', crit: ['b64'], b64: true, alg: 'HS384' })\n        .setUnprotectedHeader({ foo: 'bar' })\n        .setUnprotectedHeader({ foo: 'bar' })\n    },\n    { instanceOf: TypeError, message: 'setUnprotectedHeader can only be called once' },\n  )\n\n  await t.throwsAsync(sig.sign(), {\n    message: 'inconsistent use of JWS Unencoded Payload (RFC7797)',\n    code: 'ERR_JWS_INVALID',\n  })\n})\n\ntest('General JWS verify format validation', async (t) => {\n  const sig = new GeneralSign(t.context.plaintext)\n\n  sig\n    .addSignature(t.context.secret)\n    .setProtectedHeader({ bar: 'baz' })\n    .setUnprotectedHeader({ alg: 'HS256' })\n\n  const generalJws = await sig.sign()\n\n  {\n    await t.notThrowsAsync(async () => {\n      await generalVerify(\n        await new GeneralSign(new Uint8Array())\n          .addSignature(t.context.secret)\n          .setProtectedHeader({ alg: 'HS256' })\n          .sign(),\n        t.context.secret,\n      )\n    })\n  }\n\n  {\n    await t.throwsAsync(generalVerify(null, t.context.secret), {\n      message: 'General JWS must be an object',\n      code: 'ERR_JWS_INVALID',\n    })\n  }\n\n  {\n    await t.throwsAsync(generalVerify({ signatures: null }, t.context.secret), {\n      message: 'JWS Signatures missing or incorrect type',\n      code: 'ERR_JWS_INVALID',\n    })\n  }\n\n  {\n    await t.throwsAsync(generalVerify({ signatures: [null] }, t.context.secret), {\n      message: 'JWS Signatures missing or incorrect type',\n      code: 'ERR_JWS_INVALID',\n    })\n  }\n\n  {\n    const jws = { payload: generalJws.payload, signatures: [] }\n\n    await t.throwsAsync(generalVerify(jws, t.context.secret), {\n      message: 'signature verification failed',\n      code: 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED',\n    })\n  }\n\n  {\n    await t.notThrowsAsync(generalVerify(generalJws, t.context.secret))\n  }\n\n  {\n    const { payload, signatures } = generalJws\n    const jws = { payload, signatures: [...signatures, {}] }\n\n    await t.notThrowsAsync(generalVerify(jws, t.context.secret))\n  }\n\n  {\n    const { payload, signatures } = generalJws\n    const jws = { payload, signatures: [{}, ...signatures] }\n\n    await t.notThrowsAsync(generalVerify(jws, t.context.secret))\n  }\n})\n\ntest('sign empty data', async (t) => {\n  const jws = await new GeneralSign(new Uint8Array(0))\n    .addSignature(new Uint8Array(32))\n    .setProtectedHeader({ alg: 'HS256' })\n    .sign()\n\n  t.is(jws.payload, '')\n\n  const { payload } = await generalVerify(jws, new Uint8Array(32))\n  t.is(payload.byteLength, 0)\n})\n"
  },
  {
    "path": "test/jws/restrictions.test.ts",
    "content": "import test from 'ava'\nimport * as crypto from 'crypto'\n\nimport {\n  base64url,\n  exportPKCS8,\n  flattenedDecrypt,\n  FlattenedEncrypt,\n  FlattenedSign,\n  flattenedVerify,\n  generateKeyPair,\n  importJWK,\n} from '../../src/index.js'\n\nfunction pubjwk(jwk) {\n  const { d, p, q, dp, dq, qi, ...publicJwk } = jwk\n  return publicJwk\n}\n\ntest.before((t) => {\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n  t.context.payload = encode('It’s a dangerous business, Frodo, going out your door.')\n  t.context.rsa2040 = {\n    e: 'AQAB',\n    n: '4waoB9XUAsGc-bhkfY-v3hKEqmLYF4nS-8nji5R5KoOOeWC2hCkvbMfd2IlKRdMU7EmGXNx2BD2FVIqN9mWyZKJlzR2125lgJ-VxCymGv1A9057LEAFIrXsCUqwjPO07hCzZNv8IAAQzq53pnlAgb3TbfrxW24tamhCtaKHb5upAwo4jhYnfzex2--vD7mPxMoTuikno-eD_hxYmA52Uh1gu3wEWy44KA6aFJBpP7m4G5StuHSCXxiOWDaqMeFsMX1jqrom7SwbGJ7j0sf3ZqWrZR4x1pB3wk5Sixi_lmDfOkXhiizYnvJJ5rzr_f0bVdXeAe2U8vpEJSQeA36T7',\n    d: 'T7ZPm2it50XZ-yiOSDQCWSQBZt4L57_hz7ykY6b_IDlO9jlJ_H-FgllvAI-7_2ZNC2YJgmN6IKUFQpjfnas5hvIqcmnDJ9bjlz6NgZDUGipvevVfcUAyJ49wUlzUhpj5c8BXiGLliTPwfIqWs5qIuPm78_TnPnDgoAXJDVr_njr_C6CJFVfWni_6MTeT8iSApGrIJ-tovLlUWSQAyKfWT0QK8dclmREla6-B4YPFwMuBViiSI8dGFpw1O-sEn7D1aMWRepWKr-dgvukuksdL39LxBeGz-iHpI_DMdSB63t5kyjT7GPlbBkD__4ie_Vl4bG30dUZvH_Vt6nXxyXEh',\n    p: 'D0TqaIEyAQHzW1SnC_b1AM9sehg6baMhw4mwSQHqVQreS6a2FKor2xVUdWzT3EurRJ-NThGyi81b30MsKjV_eZ1pIA2r5ulab5CgsV4pkk9LZPZYtz4Rylv9RY3ArtBxziF_BPhTbyy5LXUr5TZUpTQn-LGPOc2sjDaB80uD9XE',\n    q: 'Dt5ET14bw-tNwsgBK-IuhuPzxeCYSi6AkiDqdJuykcN8z8Of-OyPbQSVgTNbvQSZ1anaV0-pvrkER5ilIjcaGtaBmQmCUZe0vKBynakRWXR16SE2mqJAjAmO6VD25cxdnNghdg8ue5XsdyjuQ0dnTXibsIcVyjfaIZgjbhi6mys',\n    dp: 'BD0cWXBsAi2ZceQZD1A6CUSLl4U8Sw07JT4Gyu2WMI940EVyTGBFFmdgb8yLL59t5vnnzyFIkFisxVivXPRG8-rHsRc6fjqPWWMryLEcFzqd8mQUkqHPbH6G25UTRTQmM5PG4AlTmAwxR7Y8PkAL1WSaKAaafPBkkvPatUBkXHE',\n    dq: 'Bv-nBfkVdr6PRu2gZ4i7P_GTMQTMirai_KYT1rnnb2emm6HI7oJj7PwoZ73GJA5DX2jphwnPrCApHI6ExLtNRW7NaD0qo7-WaufXq9EGgqYoTom8y0MuwPxK0hazcW4mborqDUmOJsxml5yjsvWscbIhDxI3No3d1sxneQ6Y4Cs',\n    qi: 'AkpKJwYKvaB73G7IQK5yxXCOvypwSEUK1bOcbhOZSQPPNtKvov11dVsGs-pqHo0Su06IXQv0Ayyy3uxXvsY8CyZ3CbPWMXM06Z3Gr0kZWWfNu8NiFwXvkbe24P-KeXIQGFTfdqSMTfm2an1YNE9e9F36rZ0EkhdKzmwzudA7jtw',\n    kty: 'RSA',\n  }\n  t.context.rsa2048 = {\n    e: 'AQAB',\n    n: '3egkthDOqRIif9azx83Q-HKcVNUeDALom8e5L1rjljB82EKYt5zgfKlgLW4NuJQgLDx5jA7Ez_nz-8lIcVTez-C75_M-Thv2wLhk4ZAYAZZPEmZr76zH8-lClnhxcqFnkOABqLmopr2gF1gBG_IkqEnH_h_yH486YkCd0G2ZNJAzjCOCQMR5pzBnIxC4YUAX7r_-9ilQ8Lv3MSJ0MLv6cujJTneyjWnoh_SfOXRsY6f3gkfR9APj9Q5A8PA8gvbYyN8EHr4OYb1KwNjs_0_X0Aq0e1NJx3H5eiZe6UaFleIbEVZYoNtlNJO3kmGESaxepkWTRAqBZVTfj4KnKX_9Ow',\n    d: 'Q17sbl4x8ACyeq97i4jADf312oeNhMYJSupbHbZxbDKyZJHrfatiOFbP_VrxTX2jOurtWAlP1Xiki2fz13yV3PT095nQ67PvuVkCP70YnLq-rO5tjKmfVz0VW0ub3dqE7-YietBLFLxzc0Ljq1FbscAcuNmID-7TIetOPm5X2i3wxOuiEV2xz1nHVuys3yoO3z4rAitGFl943k71P4FKxK9mp9oTQTnDfKauP0eSOD10L2NiYLkUTg9YC8A0EQopdZatDVAz3hWitNpJg28fWe7rp7yR2YBb4nFcNuygZmzEzp7x0r87NnTt9t4Hjd1rNFbd3hdT6Dy9_pejkmdU2Q',\n    p: '8_HZDF8wp0ujYxiyvAXOL6Xsnv08bQ80uzDOGCnHWWKeFn8n43gc49AdBiJ2ljmfQxExiK0wmetR76zdxTJBIWQdGI2ZJkb6lAIOEBhrXzrWXUSMPgc3qYbQRkmexrAAdwG1nWUymMDd36K5d_YEmL172a-gyEAXMGGW81AaeVU',\n    q: '6N9-STJXjcrwedkJpmmjKLBpU_Nw0UfpKAkh3Xf6jpaF-A2Cvr07JqDVzExMfpYDCcki7IW8SLK5wXVfWCZqXXl4bsb5LAJLnRIglgnDxItlmRf5CWHw7lmBD6BguEIhXU3xPiNrK3XiBVS4k2yDaYHHoAPYXDfTCGpbts7SXE8',\n    dp: 'k_OmtH43P__8BGpCXQ8YUoXL0VG9iFekn7OmC7mrEmdhgjt0sd1ziCf8sm_MhKhGE6Ml68M-qtuyQi8SAjvMjLfvfajDrhd2erYUWWa2GHfS85ZTiHtQIx2EzFxyVAcDASqkP-XUnhi7eJt06XDosMqbhxeh6FIWvl0x9DgtFlE',\n    dq: 'UqK8VY0ftJlHLHXwDrV9yHqRZdEFP76c5jAXbFee-epAL_3bX4QW8WYxeAW7P1BMU7SkR_pNDh8d-6CC7Oz04aaxLd49nXhTDLHaDmP4rE4rB2CSZtnyfSIVwk3PBJOy80EtUjePWCTEx8-AkA_5sf7zr7ytkkvc_yd-1CggTdE',\n    qi: 'd72eV7EbpvaSA3ZiQdGXpMMr41o0ih1WnV80Bxraugj1vMqxLlhVdDhDCVoF3LEoXVz8n2NEl1F6k2o3Gt9C5pXUDJwRGS41FwYVp8RN-aWviJM43mM0oQndJomZyDzjOKzpTzlNlAkFQQbfoagc4sbg-0JxK9rWdnMDW5AR1BU',\n    kty: 'RSA',\n  }\n})\n\nasync function testRSAsig(t, alg) {\n  const message = `${alg} requires key modulusLength to be 2048 bits or larger`\n  const keyBad = t.context.rsa2040\n  const keyOk = t.context.rsa2048\n  await t.throwsAsync(\n    new FlattenedSign(t.context.payload)\n      .setProtectedHeader({ alg })\n      .sign(await importJWK(keyBad, alg)),\n    { instanceOf: TypeError, message },\n  )\n\n  const jws = await new FlattenedSign(t.context.payload)\n    .setProtectedHeader({ alg })\n    .sign(await importJWK(keyOk, alg))\n\n  await t.throwsAsync(flattenedVerify(jws, await importJWK(pubjwk(keyBad), alg)), {\n    instanceOf: TypeError,\n    message,\n  })\n}\ntestRSAsig.title = (title, alg) => `${alg} requires key modulusLength to be 2048 bits or larger`\n\nasync function testRSAenc(t, alg) {\n  const message = `${alg} requires key modulusLength to be 2048 bits or larger`\n  const keyBad = t.context.rsa2040\n  const keyOk = t.context.rsa2048\n  await t.throwsAsync(\n    new FlattenedEncrypt(t.context.payload)\n      .setProtectedHeader({ alg, enc: 'A256GCM' })\n      .encrypt(await importJWK(pubjwk(keyBad), alg)),\n    { instanceOf: TypeError, message },\n  )\n\n  const jwe = await new FlattenedEncrypt(t.context.payload)\n    .setProtectedHeader({ alg, enc: 'A256GCM' })\n    .encrypt(await importJWK(pubjwk(keyOk), alg))\n\n  await t.throwsAsync(flattenedDecrypt(jwe, await importJWK(keyBad, alg)), {\n    instanceOf: TypeError,\n    message,\n  })\n}\ntestRSAenc.title = (title, alg) => `${alg} requires key modulusLength to be 2048 bits or larger`\n\nasync function testECDSASigEncoding(t, alg) {\n  const { privateKey, publicKey } = await generateKeyPair(alg, { extractable: true })\n\n  const jws = await new FlattenedSign(t.context.payload)\n    .setProtectedHeader({ alg })\n    .sign(privateKey)\n\n  const derEncodedSignature = base64url.encode(\n    crypto.sign(`sha${alg.slice(2, 5)}`, Buffer.from('foo'), await exportPKCS8(privateKey)),\n  )\n\n  await t.throwsAsync(flattenedVerify({ ...jws, signature: derEncodedSignature }, publicKey), {\n    message: 'signature verification failed',\n    code: 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED',\n  })\n}\ntestECDSASigEncoding.title = (title, alg) => `${alg} swallows invalid signature encoding errors`\n\ntest(testRSAsig, 'RS256')\ntest(testRSAsig, 'PS256')\ntest(testRSAsig, 'RS384')\ntest(testRSAsig, 'PS384')\ntest(testRSAsig, 'RS512')\ntest(testRSAsig, 'PS512')\n\ntest(testRSAenc, 'RSA-OAEP')\ntest(testRSAenc, 'RSA-OAEP-256')\ntest(testRSAenc, 'RSA-OAEP-384')\ntest(testRSAenc, 'RSA-OAEP-512')\n\ntest(testECDSASigEncoding, 'ES256')\ntest(testECDSASigEncoding, 'ES384')\ntest(testECDSASigEncoding, 'ES512')\n"
  },
  {
    "path": "test/jws/unencoded.test.ts",
    "content": "import test from 'ava'\n\nimport { FlattenedSign, flattenedVerify } from '../../src/index.js'\nconst encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n\ntest('JSON Web Signature (JWS) Unencoded Payload Option', async (t) => {\n  const jws = await new FlattenedSign(encode('foo'))\n    .setProtectedHeader({ alg: 'HS256', b64: false, crit: ['b64'] })\n    .sign(new Uint8Array(32))\n\n  t.deepEqual(jws, {\n    payload: '',\n    protected: 'eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19',\n    signature: 'VklKdp4tVYD61VNPDBTqxqdEQcUL3JK-D4dGXu9NvWs',\n  })\n\n  await t.notThrowsAsync(flattenedVerify({ ...jws, payload: 'foo' }, new Uint8Array(32)))\n  await t.notThrowsAsync(flattenedVerify({ ...jws, payload: encode('foo') }, new Uint8Array(32)))\n})\n\ntest('b64 check', async (t) => {\n  await t.throwsAsync(\n    new FlattenedSign(encode('foo'))\n      .setProtectedHeader({ alg: 'HS256', b64: null, crit: ['b64'] })\n      .sign(new Uint8Array(32)),\n    {\n      code: 'ERR_JWS_INVALID',\n      message: 'The \"b64\" (base64url-encode payload) Header Parameter must be a boolean',\n    },\n  )\n  await t.throwsAsync(\n    new FlattenedSign(encode('foo'))\n      .setProtectedHeader({ alg: 'HS256', crit: ['b64'] })\n      .sign(new Uint8Array(32)),\n    { code: 'ERR_JWS_INVALID', message: 'Extension Header Parameter \"b64\" is missing' },\n  )\n  await t.throwsAsync(\n    new FlattenedSign(encode('foo'))\n      .setProtectedHeader({ alg: 'HS256', crit: ['b64'] })\n      .setUnprotectedHeader({ b64: false })\n      .sign(new Uint8Array(32)),\n    {\n      code: 'ERR_JWS_INVALID',\n      message: 'Extension Header Parameter \"b64\" MUST be integrity protected',\n    },\n  )\n})\n"
  },
  {
    "path": "test/jwt/decrypt.test.ts",
    "content": "import test from 'ava'\nimport timekeeper from 'timekeeper'\n\nimport { EncryptJWT, jwtDecrypt, CompactEncrypt } from '../../src/index.js'\n\nconst now = 1604416038\n\ntest.before(async (t) => {\n  t.context.secret = new Uint8Array(32)\n  t.context.payload = { 'urn:example:claim': true }\n\n  timekeeper.freeze(now * 1000)\n})\n\ntest.after(timekeeper.reset)\n\ntest('Basic JWT Claims Set verification', async (t) => {\n  const issuer = 'urn:example:issuer'\n  const subject = 'urn:example:subject'\n  const audience = 'urn:example:audience'\n  const jti = 'urn:example:jti'\n  const nbf = now - 10\n  const iat = now - 20\n  const exp = now + 10\n  const typ = 'urn:example:typ'\n  const jwt = await new EncryptJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'dir', enc: 'A256GCM', typ })\n    .setIssuer(issuer)\n    .setSubject(subject)\n    .setAudience(audience)\n    .setJti(jti)\n    .setNotBefore(nbf)\n    .setExpirationTime(exp)\n    .setIssuedAt(iat)\n    .encrypt(t.context.secret)\n\n  t.deepEqual(\n    await jwtDecrypt(jwt, t.context.secret, {\n      issuer,\n      subject,\n      audience,\n      jti,\n      typ,\n      maxTokenAge: '30s',\n    }),\n    {\n      payload: {\n        aud: 'urn:example:audience',\n        exp: 1604416048,\n        iat: 1604416018,\n        iss: 'urn:example:issuer',\n        jti: 'urn:example:jti',\n        nbf: 1604416028,\n        sub: 'urn:example:subject',\n        'urn:example:claim': true,\n      },\n      protectedHeader: {\n        alg: 'dir',\n        enc: 'A256GCM',\n        typ: 'urn:example:typ',\n      },\n    },\n  )\n  await t.notThrowsAsync(jwtDecrypt(new TextEncoder().encode(jwt), t.context.secret))\n})\n\ntest('Payload must be an object', async (t) => {\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n  for (const value of [0, 1, -1, true, false, null, [], '']) {\n    const token = await new CompactEncrypt(encode(JSON.stringify(value)))\n      .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n      .encrypt(t.context.secret)\n    await t.throwsAsync(jwtDecrypt(token, t.context.secret), {\n      code: 'ERR_JWT_INVALID',\n      message: 'JWT Claims Set must be a top-level JSON object',\n    })\n  }\n})\n\ntest('Payload must JSON parseable', async (t) => {\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n  const token = await new CompactEncrypt(encode('{'))\n    .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n    .encrypt(t.context.secret)\n  await t.throwsAsync(jwtDecrypt(token, t.context.secret), {\n    code: 'ERR_JWT_INVALID',\n    message: 'JWT Claims Set must be a top-level JSON object',\n  })\n})\n\ntest('contentEncryptionAlgorithms and keyManagementAlgorithms options', async (t) => {\n  const jwt = await new EncryptJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n    .encrypt(t.context.secret)\n\n  await t.throwsAsync(\n    jwtDecrypt(jwt, t.context.secret, {\n      keyManagementAlgorithms: ['RSA-OAEP'],\n    }),\n    {\n      code: 'ERR_JOSE_ALG_NOT_ALLOWED',\n      message: '\"alg\" (Algorithm) Header Parameter value not allowed',\n    },\n  )\n  await t.throwsAsync(\n    jwtDecrypt(jwt, t.context.secret, {\n      keyManagementAlgorithms: [null],\n    }),\n    {\n      instanceOf: TypeError,\n      message: '\"keyManagementAlgorithms\" option must be an array of strings',\n    },\n  )\n  await t.throwsAsync(\n    jwtDecrypt(jwt, t.context.secret, {\n      contentEncryptionAlgorithms: ['A128GCM'],\n    }),\n    {\n      code: 'ERR_JOSE_ALG_NOT_ALLOWED',\n      message: '\"enc\" (Encryption Algorithm) Header Parameter value not allowed',\n    },\n  )\n  await t.throwsAsync(\n    jwtDecrypt(jwt, t.context.secret, {\n      contentEncryptionAlgorithms: [null],\n    }),\n    {\n      instanceOf: TypeError,\n      message: '\"contentEncryptionAlgorithms\" option must be an array of strings',\n    },\n  )\n})\n\ntest('typ verification', async (t) => {\n  {\n    const typ = 'urn:example:typ'\n    const jwt = await new EncryptJWT(t.context.payload)\n      .setProtectedHeader({ alg: 'dir', enc: 'A256GCM', typ })\n      .encrypt(t.context.secret)\n\n    await t.notThrowsAsync(\n      jwtDecrypt(jwt, t.context.secret, {\n        typ: 'application/urn:example:typ',\n      }),\n    )\n\n    await t.throwsAsync(\n      jwtDecrypt(jwt, t.context.secret, {\n        typ: 'urn:example:typ:2',\n      }),\n      { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"typ\" JWT header value' },\n    )\n\n    await t.throwsAsync(\n      jwtDecrypt(jwt, t.context.secret, {\n        typ: 'application/urn:example:typ:2',\n      }),\n      { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"typ\" JWT header value' },\n    )\n  }\n  {\n    const typ = 'application/urn:example:typ'\n    const jwt = await new EncryptJWT(t.context.payload)\n      .setProtectedHeader({ alg: 'dir', enc: 'A256GCM', typ })\n      .encrypt(t.context.secret)\n\n    await t.notThrowsAsync(\n      jwtDecrypt(jwt, t.context.secret, {\n        typ: 'urn:example:typ',\n      }),\n    )\n\n    await t.throwsAsync(\n      jwtDecrypt(jwt, t.context.secret, {\n        typ: 'application/urn:example:typ:2',\n      }),\n      { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"typ\" JWT header value' },\n    )\n\n    await t.throwsAsync(\n      jwtDecrypt(jwt, t.context.secret, {\n        typ: 'urn:example:typ:2',\n      }),\n      { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"typ\" JWT header value' },\n    )\n  }\n})\n\ntest('Issuer[] verification', async (t) => {\n  const issuer = 'urn:example:issuer'\n  const jwt = await new EncryptJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n    .setIssuer(issuer)\n    .encrypt(t.context.secret)\n\n  await t.notThrowsAsync(\n    jwtDecrypt(jwt, t.context.secret, {\n      issuer: [issuer],\n    }),\n  )\n})\n\ntest('Issuer[] verification failed', async (t) => {\n  const issuer = 'urn:example:issuer'\n  const jwt = await new EncryptJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n    .setIssuer(issuer)\n    .encrypt(t.context.secret)\n\n  await t.throwsAsync(\n    jwtDecrypt(jwt, t.context.secret, {\n      issuer: [],\n    }),\n    { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"iss\" claim value' },\n  )\n})\n\ntest('Issuer[] verification failed []', async (t) => {\n  const issuer = 'urn:example:issuer'\n  const jwt = await new EncryptJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n    .setIssuer([issuer])\n    .encrypt(t.context.secret)\n\n  await t.throwsAsync(\n    jwtDecrypt(jwt, t.context.secret, {\n      issuer: [],\n    }),\n    { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"iss\" claim value' },\n  )\n})\n\ntest('Audience[] verification', async (t) => {\n  const audience = 'urn:example:audience'\n  const jwt = await new EncryptJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n    .setAudience(audience)\n    .encrypt(t.context.secret)\n\n  await t.notThrowsAsync(\n    jwtDecrypt(jwt, t.context.secret, {\n      audience: [audience],\n    }),\n  )\n})\n\ntest('Audience[] verification failed', async (t) => {\n  const audience = 'urn:example:audience'\n  const jwt = await new EncryptJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n    .setAudience(audience)\n    .encrypt(t.context.secret)\n\n  await t.throwsAsync(\n    jwtDecrypt(jwt, t.context.secret, {\n      audience: [],\n    }),\n    { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"aud\" claim value' },\n  )\n})\n\ntest('Audience[] verification failed []', async (t) => {\n  const audience = 'urn:example:audience'\n  const jwt = await new EncryptJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n    .setAudience([audience])\n    .encrypt(t.context.secret)\n\n  await t.throwsAsync(\n    jwtDecrypt(jwt, t.context.secret, {\n      audience: [],\n    }),\n    { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"aud\" claim value' },\n  )\n})\n\ntest('Subject verification failed', async (t) => {\n  const subject = 'urn:example:subject'\n  const jwt = await new EncryptJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n    .setSubject(subject)\n    .encrypt(t.context.secret)\n\n  await t.throwsAsync(\n    jwtDecrypt(jwt, t.context.secret, {\n      subject: 'urn:example:subject:2',\n    }),\n    { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"sub\" claim value' },\n  )\n})\n\nasync function numericDateNumber(t, claim) {\n  const jwt = await new EncryptJWT({ [claim]: null })\n    .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n    .encrypt(t.context.secret)\n\n  await t.throwsAsync(jwtDecrypt(jwt, t.context.secret), {\n    code: 'ERR_JWT_CLAIM_VALIDATION_FAILED',\n    message: `\"${claim}\" claim must be a number`,\n  })\n}\nnumericDateNumber.title = (t, claim) => `${claim} must be a number`\n\ntest('clockTolerance num', async (t) => {\n  const jwt = await new EncryptJWT({ exp: now })\n    .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n    .encrypt(t.context.secret)\n\n  await t.notThrowsAsync(jwtDecrypt(jwt, t.context.secret, { clockTolerance: 1 }))\n  await t.notThrowsAsync(jwtDecrypt(jwt, t.context.secret, { clockTolerance: '1s' }))\n  await t.throwsAsync(jwtDecrypt(jwt, t.context.secret, { clockTolerance: null }), {\n    instanceOf: TypeError,\n    message: 'Invalid clockTolerance option type',\n  })\n})\n\nasync function failingNumericDate(t, claims, assertion, decryptOptions) {\n  const jwt = await new EncryptJWT({ ...claims })\n    .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n    .encrypt(t.context.secret)\n\n  await t.throwsAsync(jwtDecrypt(jwt, t.context.secret, { ...decryptOptions }), assertion)\n}\n\ntest(\n  'exp must be in the future',\n  failingNumericDate,\n  { exp: now },\n  {\n    code: 'ERR_JWT_EXPIRED',\n    message: '\"exp\" claim timestamp check failed',\n  },\n)\n\ntest(\n  'nbf must be at least now',\n  failingNumericDate,\n  { nbf: now + 1 },\n  {\n    code: 'ERR_JWT_CLAIM_VALIDATION_FAILED',\n    message: '\"nbf\" claim timestamp check failed',\n  },\n)\n\ntest(\n  'iat must be in the past (maxTokenAge, no exp)',\n  failingNumericDate,\n  { iat: now + 1 },\n  {\n    code: 'ERR_JWT_CLAIM_VALIDATION_FAILED',\n    message: '\"iat\" claim timestamp check failed (it should be in the past)',\n  },\n  {\n    maxTokenAge: 5,\n  },\n)\n\ntest(\n  'iat must be in the past (maxTokenAge, with exp)',\n  failingNumericDate,\n  { iat: now + 1, exp: now + 10 },\n  {\n    code: 'ERR_JWT_CLAIM_VALIDATION_FAILED',\n    message: '\"iat\" claim timestamp check failed (it should be in the past)',\n  },\n  {\n    maxTokenAge: 5,\n  },\n)\n\ntest(\n  'iat must be in the past (maxTokenAge, with exp, as a string)',\n  failingNumericDate,\n  { iat: now + 1, exp: now + 10 },\n  {\n    code: 'ERR_JWT_CLAIM_VALIDATION_FAILED',\n    message: '\"iat\" claim timestamp check failed (it should be in the past)',\n  },\n  {\n    maxTokenAge: '5s',\n  },\n)\n\ntest(\n  'maxTokenAge option',\n  failingNumericDate,\n  { iat: now - 31 },\n  {\n    code: 'ERR_JWT_EXPIRED',\n    message: '\"iat\" claim timestamp check failed (too far in the past)',\n  },\n  {\n    maxTokenAge: '30s',\n  },\n)\n\nfor (const claim of ['iat', 'nbf', 'exp']) {\n  test(numericDateNumber, claim)\n}\n\nasync function replicatedClaimCheck(t, claim) {\n  {\n    const jwt = await new EncryptJWT({ [claim]: 'urn:example' })\n      .setProtectedHeader({ alg: 'dir', enc: 'A256GCM', [claim]: 'urn:example' })\n      .encrypt(t.context.secret)\n\n    await t.notThrowsAsync(jwtDecrypt(jwt, t.context.secret))\n  }\n  {\n    const jwt = await new EncryptJWT({ [claim]: 'urn:example:mismatched' })\n      .setProtectedHeader({ alg: 'dir', enc: 'A256GCM', [claim]: 'urn:example' })\n      .encrypt(t.context.secret)\n\n    await t.throwsAsync(\n      jwtDecrypt(jwt, t.context.secret, {\n        code: 'ERR_JWT_CLAIM_VALIDATION_FAILED',\n        message: `replicated \"${claim}\" claim header parameter mismatch`,\n      }),\n    )\n  }\n}\nreplicatedClaimCheck.title = (t, claim) => `${claim} header claim must match the payload`\n\nfor (const claim of ['iss', 'sub', 'aud']) {\n  test(replicatedClaimCheck, claim)\n}\n"
  },
  {
    "path": "test/jwt/encrypt.test.ts",
    "content": "import anyTest, { type TestFn } from 'ava'\nimport timekeeper from 'timekeeper'\nimport { setters } from './time_setters.js'\n\nimport { EncryptJWT, compactDecrypt, jwtDecrypt } from '../../src/index.js'\n\nconst now = 1604416038\n\ninterface Context {\n  secret: Uint8Array\n  initializationVector: Uint8Array\n  payload: Record<string, any>\n}\n\nconst test = anyTest as TestFn<Context>\n\ntest.before(async (t) => {\n  t.context.secret = new Uint8Array(16)\n  t.context.initializationVector = new Uint8Array(12)\n  t.context.payload = { 'urn:example:claim': true }\n\n  timekeeper.freeze(new Date(now * 1000))\n})\n\ntest.after(timekeeper.reset)\n\ntest('EncryptJWT', async (t) => {\n  const jwt = await new EncryptJWT(t.context.payload)\n    .setInitializationVector(t.context.initializationVector)\n    .setProtectedHeader({ alg: 'dir', enc: 'A128GCM' })\n    .encrypt(t.context.secret)\n  t.is(\n    jwt,\n    'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4R0NNIn0..AAAAAAAAAAAAAAAA.eKqvvA6MxuqSRbLVFIidFJb8x4lzPytWkoA.aglYAurAaFCoM8sCqaXSyw',\n  )\n})\n\ntest('EncryptJWT w/crit', async (t) => {\n  const expected =\n    'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4R0NNIiwiY3JpdCI6WyJodHRwOi8vb3BlbmJhbmtpbmcub3JnLnVrL2lhdCJdLCJodHRwOi8vb3BlbmJhbmtpbmcub3JnLnVrL2lhdCI6MH0..AAAAAAAAAAAAAAAA.eKqvvA6MxuqSRbLVFIidFJb8x4lzPytWkoA.Kl-auiUImwUWk4X0xpxa8A'\n  await t.throwsAsync(\n    new EncryptJWT(t.context.payload)\n      .setInitializationVector(t.context.initializationVector)\n      .setProtectedHeader({\n        alg: 'dir',\n        enc: 'A128GCM',\n        crit: ['http://openbanking.org.uk/iat'],\n        'http://openbanking.org.uk/iat': 0,\n      })\n      .encrypt(t.context.secret),\n    {\n      code: 'ERR_JOSE_NOT_SUPPORTED',\n      message: 'Extension Header Parameter \"http://openbanking.org.uk/iat\" is not recognized',\n    },\n  )\n\n  await t.notThrowsAsync(async () => {\n    const jwt = await new EncryptJWT(t.context.payload)\n      .setInitializationVector(t.context.initializationVector)\n      .setProtectedHeader({\n        alg: 'dir',\n        enc: 'A128GCM',\n        crit: ['http://openbanking.org.uk/iat'],\n        'http://openbanking.org.uk/iat': 0,\n      })\n      .encrypt(t.context.secret, { crit: { 'http://openbanking.org.uk/iat': true } })\n    t.is(jwt, expected)\n  })\n\n  await t.throwsAsync(jwtDecrypt(expected, t.context.secret), {\n    code: 'ERR_JOSE_NOT_SUPPORTED',\n    message: 'Extension Header Parameter \"http://openbanking.org.uk/iat\" is not recognized',\n  })\n  await t.notThrowsAsync(\n    jwtDecrypt(expected, t.context.secret, { crit: { 'http://openbanking.org.uk/iat': true } }),\n  )\n})\n\nasync function testJWTsetFunction(t, method, claim, value, duplicate = false, expected = value) {\n  let enc = new EncryptJWT().setProtectedHeader({ alg: 'dir', enc: 'A128GCM' })[method](value)\n\n  if (duplicate) {\n    enc = enc[`replicate${method.slice(3)}AsHeader`]()\n  }\n\n  const jwt = await enc.encrypt(t.context.secret)\n\n  const {\n    plaintext,\n    protectedHeader,\n    key: resolvedKey,\n  } = await compactDecrypt(jwt, async (header, token) => {\n    t.true('alg' in header)\n    t.true('enc' in header)\n    t.is(header.alg, 'dir')\n    t.is(header.enc, 'A128GCM')\n    t.true('ciphertext' in token)\n    t.true('iv' in token)\n    t.true('protected' in token)\n    t.true('tag' in token)\n    return t.context.secret\n  })\n  t.is(resolvedKey, t.context.secret)\n  const payload = JSON.parse(new TextDecoder().decode(plaintext))\n  t.is(payload[claim], expected)\n  if (duplicate) {\n    t.true(claim in protectedHeader)\n    t.is(protectedHeader[claim], expected)\n  } else {\n    t.false(claim in protectedHeader)\n  }\n}\ntestJWTsetFunction.title = (title, method, claim, value) =>\n  `EncryptJWT.prototype.${method} called with ${\n    value?.constructor?.name || typeof value\n  } (${value}) ${title ? ` (${title})` : ''}`\n\nfor (const [method, claim, vectors] of setters(now)) {\n  for (const [input, output = input] of vectors) {\n    test(testJWTsetFunction, method, claim, input, false, output)\n  }\n}\n\ntest('duplicated', testJWTsetFunction, 'setIssuer', 'iss', 'urn:example:issuer', true)\ntest('duplicated', testJWTsetFunction, 'setSubject', 'sub', 'urn:example:subject', true)\ntest('duplicated', testJWTsetFunction, 'setAudience', 'aud', 'urn:example:audience', true)\n\ntest('EncryptJWT.prototype.setProtectedHeader', (t) => {\n  t.throws(() => new EncryptJWT(t.context.payload).setProtectedHeader({}).setProtectedHeader({}), {\n    instanceOf: TypeError,\n    message: 'setProtectedHeader can only be called once',\n  })\n})\n\ntest('EncryptJWT.prototype.setContentEncryptionKey', (t) => {\n  t.throws(\n    () =>\n      new EncryptJWT(t.context.payload)\n        .setContentEncryptionKey(t.context.secret)\n        .setContentEncryptionKey(t.context.secret),\n    {\n      instanceOf: TypeError,\n      message: 'setContentEncryptionKey can only be called once',\n    },\n  )\n})\n\ntest('EncryptJWT.prototype.setInitializationVector', (t) => {\n  t.throws(\n    () =>\n      new EncryptJWT(t.context.payload)\n        .setInitializationVector(t.context.initializationVector)\n        .setInitializationVector(t.context.initializationVector),\n    {\n      instanceOf: TypeError,\n      message: 'setInitializationVector can only be called once',\n    },\n  )\n})\n"
  },
  {
    "path": "test/jwt/sign.test.ts",
    "content": "import test from 'ava'\nimport timekeeper from 'timekeeper'\nimport { setters } from './time_setters.js'\n\nimport { SignJWT, compactVerify, jwtVerify } from '../../src/index.js'\n\nconst now = 1604416038\n\ntest.before(async (t) => {\n  t.context.secret = new Uint8Array(32)\n  t.context.payload = { 'urn:example:claim': true }\n\n  timekeeper.freeze(now * 1000)\n})\n\ntest.after(timekeeper.reset)\n\ntest('SignJWT', async (t) => {\n  const jwt = await new SignJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'HS256' })\n    .sign(t.context.secret)\n  t.is(\n    jwt,\n    'eyJhbGciOiJIUzI1NiJ9.eyJ1cm46ZXhhbXBsZTpjbGFpbSI6dHJ1ZX0.yPnOE--rxp3rJaYy0iZaW2Vswvus05G6_ZBdXqIdjGo',\n  )\n})\n\ntest('SignJWT with default (empty) payload', async (t) => {\n  const jwt = await new SignJWT().setProtectedHeader({ alg: 'HS256' }).sign(t.context.secret)\n  t.is(jwt, 'eyJhbGciOiJIUzI1NiJ9.e30.4E_Bsx-pJi3kOW9wVXN8CgbATwP09D9V5gxh9-9zSZ0')\n})\n\ntest('SignJWT w/crit', async (t) => {\n  const expected =\n    'eyJhbGciOiJIUzI1NiIsImNyaXQiOlsiaHR0cDovL29wZW5iYW5raW5nLm9yZy51ay9pYXQiXSwiaHR0cDovL29wZW5iYW5raW5nLm9yZy51ay9pYXQiOjB9.eyJ1cm46ZXhhbXBsZTpjbGFpbSI6dHJ1ZX0.YzOrPZaNql7PpCo43HAJdj-LASP8lOmtb-Bzj9OrNAk'\n  await t.throwsAsync(\n    new SignJWT(t.context.payload)\n      .setProtectedHeader({\n        alg: 'HS256',\n        crit: ['http://openbanking.org.uk/iat'],\n        'http://openbanking.org.uk/iat': 0,\n      })\n      .sign(t.context.secret),\n    {\n      code: 'ERR_JOSE_NOT_SUPPORTED',\n      message: 'Extension Header Parameter \"http://openbanking.org.uk/iat\" is not recognized',\n    },\n  )\n\n  await t.notThrowsAsync(async () => {\n    const jwt = await new SignJWT(t.context.payload)\n      .setProtectedHeader({\n        alg: 'HS256',\n        crit: ['http://openbanking.org.uk/iat'],\n        'http://openbanking.org.uk/iat': 0,\n      })\n      .sign(t.context.secret, { crit: { 'http://openbanking.org.uk/iat': true } })\n    t.is(jwt, expected)\n  })\n\n  await t.throwsAsync(jwtVerify(expected, t.context.secret), {\n    code: 'ERR_JOSE_NOT_SUPPORTED',\n    message: 'Extension Header Parameter \"http://openbanking.org.uk/iat\" is not recognized',\n  })\n  await t.notThrowsAsync(\n    jwtVerify(expected, t.context.secret, { crit: { 'http://openbanking.org.uk/iat': true } }),\n  )\n})\n\ntest('Signed JWTs cannot use unencoded payload', async (t) => {\n  await t.throwsAsync(\n    () =>\n      new SignJWT()\n        .setProtectedHeader({ alg: 'HS256', crit: ['b64'], b64: false })\n        .sign(t.context.secret),\n    { code: 'ERR_JWT_INVALID', message: 'JWTs MUST NOT use unencoded payload' },\n  )\n  await t.throwsAsync(() => new SignJWT().sign(t.context.secret), {\n    code: 'ERR_JWS_INVALID',\n    message: 'either setProtectedHeader or setUnprotectedHeader must be called before #sign()',\n  })\n})\n\nasync function testJWTsetFunction(t, method, claim, value, expected = value) {\n  const jwt = await new SignJWT()\n    .setProtectedHeader({ alg: 'HS256' })\n    [method](value)\n    .sign(t.context.secret)\n  const { payload, key: resolvedKey } = await compactVerify(jwt, async (header, token) => {\n    t.true('alg' in header)\n    t.is(header.alg, 'HS256')\n    t.true('payload' in token)\n    t.true('protected' in token)\n    t.true('signature' in token)\n    return t.context.secret\n  })\n  t.is(resolvedKey, t.context.secret)\n  const claims = JSON.parse(new TextDecoder().decode(payload))\n  t.true(claim in claims)\n  t.is(claims[claim], expected)\n}\ntestJWTsetFunction.title = (title, method, claim, value) =>\n  `SignJWT.prototype.${method} called with ${value?.constructor?.name || typeof value} (${value})`\n\nfor (const [method, claim, vectors] of setters(now)) {\n  for (const [input, output = input] of vectors) {\n    test(testJWTsetFunction, method, claim, input, output)\n  }\n}\n"
  },
  {
    "path": "test/jwt/time_setters.ts",
    "content": "export function setters(now) {\n  const timeSetters = [\n    [0],\n    [new Date(now * 1000), now],\n    ['10s', now + 10],\n    ['+10s', now + 10],\n    ['-10s', now - 10],\n    ['+ 10s', now + 10],\n    ['- 10s', now - 10],\n    ['10s from now', now + 10],\n    ['10s ago', now - 10],\n  ]\n\n  return [\n    ['setIssuer', 'iss', [['urn:example:issuer']]],\n    ['setSubject', 'sub', [['urn:example:subject']]],\n    ['setAudience', 'aud', [['urn:example:audience']]],\n    ['setJti', 'jti', [['urn:example:jti']]],\n    ['setIssuedAt', 'iat', [[undefined, now], ...timeSetters]],\n    ['setExpirationTime', 'exp', timeSetters],\n    ['setNotBefore', 'nbf', timeSetters],\n  ]\n}\n"
  },
  {
    "path": "test/jwt/unsecured.test.ts",
    "content": "import test from 'ava'\nimport timekeeper from 'timekeeper'\nimport { setters } from './time_setters.js'\n\nimport { UnsecuredJWT, decodeJwt } from '../../src/index.js'\n\nconst now = 1604416038\n\ntest.before(async (t) => {\n  t.context.payload = { 'urn:example:claim': true }\n\n  timekeeper.freeze(now * 1000)\n})\n\ntest.after(timekeeper.reset)\n\ntest('UnsecuredJWT', async (t) => {\n  const jwt = new UnsecuredJWT(t.context.payload).encode()\n  t.is(jwt, 'eyJhbGciOiJub25lIn0.eyJ1cm46ZXhhbXBsZTpjbGFpbSI6dHJ1ZX0.')\n})\n\ntest('UnsecuredJWT validations', (t) => {\n  t.throws(() => UnsecuredJWT.decode(null), {\n    code: 'ERR_JWT_INVALID',\n    message: 'Unsecured JWT must be a string',\n  })\n  t.throws(() => UnsecuredJWT.decode('....'), {\n    code: 'ERR_JWT_INVALID',\n    message: 'Invalid Unsecured JWT',\n  })\n  t.throws(() => UnsecuredJWT.decode('..'), {\n    code: 'ERR_JWT_INVALID',\n    message: 'Invalid Unsecured JWT',\n  })\n  t.throws(() => UnsecuredJWT.decode('..foo'), {\n    code: 'ERR_JWT_INVALID',\n    message: 'Invalid Unsecured JWT',\n  })\n  t.throws(() => UnsecuredJWT.decode('eyJhbGciOiJIUzI1NiJ9.eyJ1cm46ZXhhbXBsZTpjbGFpbSI6dHJ1ZX0.'), {\n    code: 'ERR_JWT_INVALID',\n    message: 'Invalid Unsecured JWT',\n  })\n})\n\ntest('new UnsecuredJWT()', (t) => {\n  t.is(new UnsecuredJWT().encode(), 'eyJhbGciOiJub25lIn0.e30.')\n})\n\nasync function testJWTsetFunction(t, method, claim, value, expected = value) {\n  const jwt = new UnsecuredJWT()[method](value).encode()\n  const claims = decodeJwt(jwt)\n  t.true(claim in claims)\n  t.is(claims[claim], expected)\n}\ntestJWTsetFunction.title = (title, method, claim, value) =>\n  `UnsecuredJWT.prototype.${method} called with ${\n    value?.constructor?.name || typeof value\n  } (${value})`\n\nfor (const [method, claim, vectors] of setters(now)) {\n  for (const [input, output = input] of vectors) {\n    test(testJWTsetFunction, method, claim, input, output)\n  }\n}\n"
  },
  {
    "path": "test/jwt/verify.test.ts",
    "content": "import test from 'ava'\nimport timekeeper from 'timekeeper'\n\nimport { SignJWT, jwtVerify, CompactSign } from '../../src/index.js'\n\nconst now = 1604416038\n\ntest.before(async (t) => {\n  t.context.secret = new Uint8Array(32)\n  t.context.payload = { 'urn:example:claim': true }\n\n  timekeeper.freeze(now * 1000)\n})\n\ntest.after(timekeeper.reset)\n\ntest('Basic JWT Claims Set verification', async (t) => {\n  const issuer = 'urn:example:issuer'\n  const subject = 'urn:example:subject'\n  const audience = 'urn:example:audience'\n  const jti = 'urn:example:jti'\n  const nbf = now - 10\n  const iat = now - 20\n  const exp = now + 10\n  const typ = 'urn:example:typ'\n  const jwt = await new SignJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'HS256', typ })\n    .setIssuer(issuer)\n    .setSubject(subject)\n    .setAudience(audience)\n    .setJti(jti)\n    .setNotBefore(nbf)\n    .setExpirationTime(exp)\n    .setIssuedAt(iat)\n    .sign(t.context.secret)\n\n  t.deepEqual(\n    await jwtVerify(jwt, t.context.secret, {\n      issuer,\n      subject,\n      audience,\n      jti,\n      typ,\n      maxTokenAge: '30s',\n    }),\n    {\n      payload: {\n        aud: 'urn:example:audience',\n        exp: 1604416048,\n        iat: 1604416018,\n        iss: 'urn:example:issuer',\n        jti: 'urn:example:jti',\n        nbf: 1604416028,\n        sub: 'urn:example:subject',\n        'urn:example:claim': true,\n      },\n      protectedHeader: {\n        alg: 'HS256',\n        typ: 'urn:example:typ',\n      },\n    },\n  )\n  await t.notThrowsAsync(jwtVerify(new TextEncoder().encode(jwt), t.context.secret))\n})\n\ntest('Payload must be an object', async (t) => {\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n  for (const value of [0, 1, -1, true, false, null, [], '']) {\n    const token = await new CompactSign(encode(JSON.stringify(value)))\n      .setProtectedHeader({ alg: 'HS256' })\n      .sign(t.context.secret)\n    await t.throwsAsync(jwtVerify(token, t.context.secret), {\n      code: 'ERR_JWT_INVALID',\n      message: 'JWT Claims Set must be a top-level JSON object',\n    })\n  }\n})\n\ntest('incorrect hmac signature lengths', async (t) => {\n  const jwt = await new SignJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'HS256' })\n    .sign(t.context.secret)\n\n  await t.throwsAsync(jwtVerify(jwt.slice(0, -3), t.context.secret), {\n    code: 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED',\n    message: 'signature verification failed',\n  })\n})\n\ntest('Payload must JSON parseable', async (t) => {\n  const encode = TextEncoder.prototype.encode.bind(new TextEncoder())\n  const token = await new CompactSign(encode('{'))\n    .setProtectedHeader({ alg: 'HS256' })\n    .sign(t.context.secret)\n  await t.throwsAsync(jwtVerify(token, t.context.secret), {\n    code: 'ERR_JWT_INVALID',\n    message: 'JWT Claims Set must be a top-level JSON object',\n  })\n})\n\ntest('algorithms options', async (t) => {\n  const jwt = await new SignJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'HS256' })\n    .sign(t.context.secret)\n\n  await t.throwsAsync(\n    jwtVerify(jwt, t.context.secret, {\n      algorithms: ['PS256'],\n    }),\n    {\n      code: 'ERR_JOSE_ALG_NOT_ALLOWED',\n      message: '\"alg\" (Algorithm) Header Parameter value not allowed',\n    },\n  )\n  await t.throwsAsync(\n    jwtVerify(jwt, t.context.secret, {\n      algorithms: [null],\n    }),\n    {\n      instanceOf: TypeError,\n      message: '\"algorithms\" option must be an array of strings',\n    },\n  )\n})\n\ntest('typ verification', async (t) => {\n  {\n    const typ = 'urn:example:typ'\n    const jwt = await new SignJWT(t.context.payload)\n      .setProtectedHeader({ alg: 'HS256', typ })\n      .sign(t.context.secret)\n\n    await t.notThrowsAsync(\n      jwtVerify(jwt, t.context.secret, {\n        typ: 'application/urn:example:typ',\n      }),\n    )\n\n    await t.throwsAsync(\n      jwtVerify(jwt, t.context.secret, {\n        typ: 'urn:example:typ:2',\n      }),\n      { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"typ\" JWT header value' },\n    )\n\n    await t.throwsAsync(\n      jwtVerify(jwt, t.context.secret, {\n        typ: 'application/urn:example:typ:2',\n      }),\n      { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"typ\" JWT header value' },\n    )\n  }\n  {\n    const typ = 'application/urn:example:typ'\n    const jwt = await new SignJWT(t.context.payload)\n      .setProtectedHeader({ alg: 'HS256', typ })\n      .sign(t.context.secret)\n\n    await t.notThrowsAsync(\n      jwtVerify(jwt, t.context.secret, {\n        typ: 'urn:example:typ',\n      }),\n    )\n\n    await t.throwsAsync(\n      jwtVerify(jwt, t.context.secret, {\n        typ: 'application/urn:example:typ:2',\n      }),\n      { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"typ\" JWT header value' },\n    )\n\n    await t.throwsAsync(\n      jwtVerify(jwt, t.context.secret, {\n        typ: 'urn:example:typ:2',\n      }),\n      { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"typ\" JWT header value' },\n    )\n  }\n  {\n    const typ = 'text/plain'\n    const jwt = await new SignJWT(t.context.payload)\n      .setProtectedHeader({ alg: 'HS256', typ })\n      .sign(t.context.secret)\n\n    await t.notThrowsAsync(\n      jwtVerify(jwt, t.context.secret, {\n        typ: 'text/plain',\n      }),\n    )\n\n    await t.throwsAsync(\n      jwtVerify(jwt, t.context.secret, {\n        typ: 'application/text/plain',\n      }),\n      { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"typ\" JWT header value' },\n    )\n  }\n})\n\ntest('Issuer[] verification', async (t) => {\n  const issuer = 'urn:example:issuer'\n  const jwt = await new SignJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'HS256' })\n    .setIssuer(issuer)\n    .sign(t.context.secret)\n\n  await t.notThrowsAsync(\n    jwtVerify(jwt, t.context.secret, {\n      issuer: [issuer],\n    }),\n  )\n})\n\ntest('Issuer[] verification failed', async (t) => {\n  const issuer = 'urn:example:issuer'\n  const jwt = await new SignJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'HS256' })\n    .setIssuer(issuer)\n    .sign(t.context.secret)\n\n  await t.throwsAsync(\n    jwtVerify(jwt, t.context.secret, {\n      issuer: [],\n    }),\n    { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"iss\" claim value' },\n  )\n})\n\ntest('Issuer[] verification failed []', async (t) => {\n  const issuer = 'urn:example:issuer'\n  const jwt = await new SignJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'HS256' })\n    .setIssuer([issuer])\n    .sign(t.context.secret)\n\n  await t.throwsAsync(\n    jwtVerify(jwt, t.context.secret, {\n      issuer: [],\n    }),\n    { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"iss\" claim value' },\n  )\n})\n\ntest('Audience[] verification', async (t) => {\n  const audience = 'urn:example:audience'\n  const jwt = await new SignJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'HS256' })\n    .setAudience(audience)\n    .sign(t.context.secret)\n\n  await t.notThrowsAsync(\n    jwtVerify(jwt, t.context.secret, {\n      audience: [audience],\n    }),\n  )\n})\n\ntest('Audience[] verification failed', async (t) => {\n  const audience = 'urn:example:audience'\n  const jwt = await new SignJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'HS256' })\n    .setAudience(audience)\n    .sign(t.context.secret)\n\n  await t.throwsAsync(\n    jwtVerify(jwt, t.context.secret, {\n      audience: [],\n    }),\n    { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"aud\" claim value' },\n  )\n})\n\ntest('Audience[] verification failed []', async (t) => {\n  const audience = 'urn:example:audience'\n  const jwt = await new SignJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'HS256' })\n    .setAudience([audience])\n    .sign(t.context.secret)\n\n  await t.throwsAsync(\n    jwtVerify(jwt, t.context.secret, {\n      audience: [],\n    }),\n    { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"aud\" claim value' },\n  )\n})\n\ntest('Subject verification failed', async (t) => {\n  const subject = 'urn:example:subject'\n  const jwt = await new SignJWT(t.context.payload)\n    .setProtectedHeader({ alg: 'HS256' })\n    .setSubject(subject)\n    .sign(t.context.secret)\n\n  await t.throwsAsync(\n    jwtVerify(jwt, t.context.secret, {\n      subject: 'urn:example:subject:2',\n    }),\n    { code: 'ERR_JWT_CLAIM_VALIDATION_FAILED', message: 'unexpected \"sub\" claim value' },\n  )\n})\n\nasync function numericDateNumber(t, claim) {\n  const jwt = await new SignJWT({ [claim]: null })\n    .setProtectedHeader({ alg: 'HS256' })\n    .sign(t.context.secret)\n\n  await t.throwsAsync(jwtVerify(jwt, t.context.secret), {\n    code: 'ERR_JWT_CLAIM_VALIDATION_FAILED',\n    message: `\"${claim}\" claim must be a number`,\n  })\n}\nnumericDateNumber.title = (t, claim) => `${claim} must be a number`\n\ntest('clockTolerance num', async (t) => {\n  const jwt = await new SignJWT({ exp: now })\n    .setProtectedHeader({ alg: 'HS256' })\n    .sign(t.context.secret)\n\n  await t.notThrowsAsync(jwtVerify(jwt, t.context.secret, { clockTolerance: 1 }))\n  await t.notThrowsAsync(jwtVerify(jwt, t.context.secret, { clockTolerance: '1s' }))\n})\n\nasync function failingNumericDate(t, claims, assertion, verifyOptions) {\n  const jwt = await new SignJWT({ ...claims })\n    .setProtectedHeader({ alg: 'HS256' })\n    .sign(t.context.secret)\n\n  await t.throwsAsync(jwtVerify(jwt, t.context.secret, { ...verifyOptions }), assertion)\n}\n\ntest(\n  'exp must be in the future',\n  failingNumericDate,\n  { exp: now },\n  {\n    code: 'ERR_JWT_EXPIRED',\n    message: '\"exp\" claim timestamp check failed',\n  },\n)\n\ntest(\n  'nbf must be at least now',\n  failingNumericDate,\n  { nbf: now + 1 },\n  {\n    code: 'ERR_JWT_CLAIM_VALIDATION_FAILED',\n    message: '\"nbf\" claim timestamp check failed',\n  },\n)\n\ntest(\n  'iat must be in the past (maxTokenAge, no exp)',\n  failingNumericDate,\n  { iat: now + 1 },\n  {\n    code: 'ERR_JWT_CLAIM_VALIDATION_FAILED',\n    message: '\"iat\" claim timestamp check failed (it should be in the past)',\n  },\n  {\n    maxTokenAge: 5,\n  },\n)\n\ntest(\n  'iat must be in the past (maxTokenAge, with exp)',\n  failingNumericDate,\n  { iat: now + 1, exp: now + 10 },\n  {\n    code: 'ERR_JWT_CLAIM_VALIDATION_FAILED',\n    message: '\"iat\" claim timestamp check failed (it should be in the past)',\n  },\n  {\n    maxTokenAge: 5,\n  },\n)\n\ntest(\n  'iat must be in the past (maxTokenAge, with exp, as a string)',\n  failingNumericDate,\n  { iat: now + 1, exp: now + 10 },\n  {\n    code: 'ERR_JWT_CLAIM_VALIDATION_FAILED',\n    message: '\"iat\" claim timestamp check failed (it should be in the past)',\n  },\n  {\n    maxTokenAge: '5s',\n  },\n)\n\ntest(\n  'maxTokenAge option',\n  failingNumericDate,\n  { iat: now - 31 },\n  {\n    code: 'ERR_JWT_EXPIRED',\n    message: '\"iat\" claim timestamp check failed (too far in the past)',\n  },\n  {\n    maxTokenAge: '30s',\n  },\n)\n\nfor (const claim of ['iat', 'nbf', 'exp']) {\n  test(numericDateNumber, claim)\n}\n\ntest('Signed JWTs cannot use unencoded payload', async (t) => {\n  await t.throwsAsync(\n    jwtVerify(\n      'eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19.foo.VklKdp4tVYD61VNPDBTqxqdEQcUL3JK-D4dGXu9NvWs',\n      t.context.secret,\n    ),\n    { code: 'ERR_JWT_INVALID', message: 'JWTs MUST NOT use unencoded payload' },\n  )\n})\n\ntest('signatures are compared before claim set', async (t) => {\n  // https://github.com/panva/jose/discussions/447\n  const jwt = await new SignJWT({ exp: 0 })\n    .setProtectedHeader({ alg: 'HS256' })\n    .sign(t.context.secret)\n\n  // with valid secret should throw exp failing to verify\n  await t.throwsAsync(jwtVerify(jwt, t.context.secret), { code: 'ERR_JWT_EXPIRED' })\n\n  // with invalid secret should throw signature failing to verify\n  await t.throwsAsync(jwtVerify(jwt, new Uint8Array([0x00, 0x01])), {\n    code: 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED',\n  })\n})\n\ntest('requiredClaims claims check', async (t) => {\n  const jwt = await new SignJWT({\n    ...t.context.payload,\n  })\n    .setProtectedHeader({ alg: 'HS256' })\n    .sign(t.context.secret)\n\n  const requiredClaims = ['nbf']\n\n  for (const [claim, option] of [\n    ['iss', 'issuer'],\n    ['aud', 'audience'],\n    ['iat', 'maxTokenAge'],\n    ['sub', 'subject'],\n  ]) {\n    await t.throwsAsync(jwtVerify(jwt, t.context.secret, { [option]: 'foo' }), {\n      code: 'ERR_JWT_CLAIM_VALIDATION_FAILED',\n      message: `missing required \"${claim}\" claim`,\n    })\n    await t.throwsAsync(jwtVerify(jwt, t.context.secret, { [option]: 'foo', requiredClaims }), {\n      code: 'ERR_JWT_CLAIM_VALIDATION_FAILED',\n      message: `missing required \"${claim}\" claim`,\n    })\n  }\n  await t.throwsAsync(jwtVerify(jwt, t.context.secret, { requiredClaims }), {\n    code: 'ERR_JWT_CLAIM_VALIDATION_FAILED',\n    message: `missing required \"nbf\" claim`,\n  })\n\n  t.deepEqual(requiredClaims, ['nbf'])\n})\n"
  },
  {
    "path": "test/tsconfig.json",
    "content": "{\n  \"include\": [\"**/*.test.ts\"],\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ES2022\",\n    \"moduleResolution\": \"Node\",\n    \"strict\": true,\n    \"noEmit\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noImplicitAny\": true,\n    \"esModuleInterop\": true\n  }\n}\n"
  },
  {
    "path": "test/unit/buffer_utils.test.ts",
    "content": "import test from 'ava'\n\nimport { uint32be } from '../../src/lib/buffer_utils.js'\n\ntest('lib/buffer_utils.ts', (t) => {\n  t.throws(() => uint32be(-1), { instanceOf: RangeError })\n  t.throws(() => uint32be(2 ** 32), { instanceOf: RangeError })\n})\n"
  },
  {
    "path": "test/unit/cek.test.ts",
    "content": "import test from 'ava'\n\nimport { generateCek } from '../../src/lib/content_encryption.js'\n\ntest('lib/cek.ts', (t) => {\n  t.throws(() => generateCek('foo'), {\n    code: 'ERR_JOSE_NOT_SUPPORTED',\n    message: 'Unsupported JWE Algorithm: foo',\n  })\n})\n"
  },
  {
    "path": "test/unit/check_iv_length.test.ts",
    "content": "import test from 'ava'\n\nimport { checkIvLength } from '../../src/lib/content_encryption.js'\n\ntest('lib/check_iv_length.ts', (t) => {\n  t.throws(() => checkIvLength('A256GCM', new Uint8Array(13)), {\n    code: 'ERR_JWE_INVALID',\n    message: 'Invalid Initialization Vector length',\n  })\n  t.notThrows(() => checkIvLength('A256GCM', new Uint8Array(12)))\n})\n"
  },
  {
    "path": "test/unit/check_key_type.test.ts",
    "content": "import test from 'ava'\n\nconst types = 'CryptoKey, KeyObject, JSON Web Key, or Uint8Array'\nconst asymmetricTypes = 'CryptoKey, KeyObject, or JSON Web Key'\n\nimport * as lib from '../../src/index.js'\nimport { checkKeyType } from '../../src/lib/check_key_type.js'\n\ntest('lib/check_key_type.ts', async (t) => {\n  const expected = {\n    instanceOf: TypeError,\n    message: new RegExp(`^Key for the .+ algorithm must be (?:one )?of type ${types}\\\\.`),\n  }\n\n  t.throws(() => checkKeyType('HS256'), expected)\n  t.throws(() => checkKeyType('HS256', undefined), expected)\n  t.throws(() => checkKeyType('HS256', null), expected)\n  t.throws(() => checkKeyType('HS256', 1), expected)\n  t.throws(() => checkKeyType('HS256', 0), expected)\n  t.throws(() => checkKeyType('HS256', true), expected)\n  t.throws(() => checkKeyType('HS256', Boolean), expected)\n  t.throws(() => checkKeyType('HS256', []), expected)\n  t.throws(() => checkKeyType('HS256', ''), expected)\n  t.throws(() => checkKeyType('HS256', 'foo'), expected)\n\n  t.throws(() => checkKeyType('PS256', new Uint8Array()), {\n    ...expected,\n    message: new RegExp(`^Key for the .+ algorithm must be (?:one )?of type ${asymmetricTypes}\\\\.`),\n  })\n  let secret = await lib.generateSecret('HS256')\n  t.throws(() => checkKeyType('PS256', secret), {\n    ...expected,\n    message: 'CryptoKey instances for asymmetric algorithms must not be of type \"secret\"',\n  })\n\n  t.notThrows(() => checkKeyType('dir', new Uint8Array()))\n  t.notThrows(() => checkKeyType('HS256', new Uint8Array()))\n  t.notThrows(() => checkKeyType('PBES2-HS256+A128KW', new Uint8Array()))\n  t.notThrows(() => checkKeyType('A256GCMKW', new Uint8Array()))\n  t.notThrows(() => checkKeyType('A256KW', new Uint8Array()))\n\n  secret = await lib.generateSecret('A256GCMKW')\n  t.notThrows(() => checkKeyType('dir', secret))\n  secret = await lib.generateSecret('HS256')\n  t.notThrows(() => checkKeyType('HS256', secret))\n  secret = await lib.generateSecret('A256GCMKW')\n  t.notThrows(() => checkKeyType('A256GCMKW', secret))\n  secret = await lib.generateSecret('A256KW')\n  t.notThrows(() => checkKeyType('A256KW', secret))\n\n  let keypair = await lib.generateKeyPair('PS256')\n  t.throws(() => checkKeyType('PS256', keypair.publicKey, 'sign'), {\n    ...expected,\n    message: 'CryptoKey instances for asymmetric algorithm signing must be of type \"private\"',\n  })\n\n  t.throws(() => checkKeyType('HS256', keypair.privateKey), {\n    ...expected,\n    message: 'CryptoKey instances for symmetric algorithms must be of type \"secret\"',\n  })\n\n  t.throws(() => checkKeyType('PS256', keypair.privateKey, 'verify'), {\n    ...expected,\n    message: 'CryptoKey instances for asymmetric algorithm verifying must be of type \"public\"',\n  })\n\n  keypair = await lib.generateKeyPair('ECDH-ES')\n  t.throws(() => checkKeyType('ECDH-ES', keypair.publicKey, 'decrypt'), {\n    ...expected,\n    message: 'CryptoKey instances for asymmetric algorithm decryption must be of type \"private\"',\n  })\n\n  t.throws(() => checkKeyType('ECDH-ES', keypair.privateKey, 'encrypt'), {\n    ...expected,\n    message: 'CryptoKey instances for asymmetric algorithm encryption must be of type \"public\"',\n  })\n})\n"
  },
  {
    "path": "test/unit/check_key_type_jwk.test.ts",
    "content": "import test from 'ava'\n\nconst types = 'CryptoKey, KeyObject, JSON Web Key, or Uint8Array'\nconst asymmetricTypes = 'CryptoKey, KeyObject, or JSON Web Key'\n\nimport { checkKeyType } from '../../src/lib/check_key_type.js'\n\ntest('lib/check_key_type.ts with JWK', async (t) => {\n  const expected = {\n    instanceOf: TypeError,\n    message: new RegExp(`^Key for the .+ algorithm must be (?:one )?of type ${types}\\\\.`),\n  }\n\n  t.throws(() => checkKeyType('HS256'), expected)\n  t.throws(() => checkKeyType('HS256', undefined), expected)\n  t.throws(() => checkKeyType('HS256', null), expected)\n  t.throws(() => checkKeyType('HS256', 1), expected)\n  t.throws(() => checkKeyType('HS256', 0), expected)\n  t.throws(() => checkKeyType('HS256', true), expected)\n  t.throws(() => checkKeyType('HS256', Boolean), expected)\n  t.throws(() => checkKeyType('HS256', []), expected)\n  t.throws(() => checkKeyType('HS256', ''), expected)\n  t.throws(() => checkKeyType('HS256', 'foo'), expected)\n\n  t.throws(() => checkKeyType('PS256', new Uint8Array()), {\n    ...expected,\n    message: new RegExp(`^Key for the .+ algorithm must be (?:one )?of type ${asymmetricTypes}\\\\.`),\n  })\n\n  t.notThrows(() => checkKeyType('HS256', { kty: 'oct', k: '' }, 'sign'))\n  t.notThrows(() => checkKeyType('HS256', { kty: 'oct', k: '', use: 'sig' }, 'sign'))\n  t.notThrows(() => checkKeyType('HS256', { kty: 'oct', k: '', key_ops: ['sign'] }, 'sign'))\n  t.notThrows(() => checkKeyType('HS256', { kty: 'oct', k: '', alg: 'HS256' }))\n\n  t.throws(() => checkKeyType('HS256', { kty: 'oct', k: '', use: 'enc' }, 'sign'), {\n    ...expected,\n    message: 'Invalid key for this operation, its \"use\" must be \"sig\" when present',\n  })\n\n  t.throws(() => checkKeyType('HS256', { kty: 'oct', k: '', alg: 'HS384' }, 'sign'), {\n    ...expected,\n    message: 'Invalid key for this operation, its \"alg\" must be \"HS256\" when present',\n  })\n\n  t.throws(() => checkKeyType('HS256', { kty: 'RSA' }), {\n    ...expected,\n    message:\n      'JSON Web Key for symmetric algorithms must have JWK \"kty\" (Key Type) equal to \"oct\" and the JWK \"k\" (Key Value) present',\n  })\n\n  t.notThrows(() => checkKeyType('PS256', { kty: 'RSA' }, 'verify'))\n  t.throws(() => checkKeyType('PS256', { kty: 'RSA', d: '' }, 'verify'), {\n    ...expected,\n    message: 'JSON Web Key for this operation must be a public JWK',\n  })\n\n  t.notThrows(() => checkKeyType('PS256', { kty: 'RSA', d: '' }, 'sign'))\n  t.throws(() => checkKeyType('PS256', { kty: 'RSA' }, 'sign'), {\n    ...expected,\n    message: 'JSON Web Key for this operation must be a private JWK',\n  })\n})\n"
  },
  {
    "path": "test/unit/iv.test.ts",
    "content": "import test from 'ava'\n\nimport { generateIv } from '../../src/lib/content_encryption.js'\n\ntest('lib/iv.ts', (t) => {\n  t.throws(() => generateIv('foo'), {\n    code: 'ERR_JOSE_NOT_SUPPORTED',\n    message: 'Unsupported JWE Algorithm: foo',\n  })\n})\n"
  },
  {
    "path": "test/unit/secs.test.ts",
    "content": "import test from 'ava'\n\nconst { secs } = await import('../../src/lib/jwt_claims_set.js')\n\ntest('lib/secs.ts', (t) => {\n  for (const sign of ['+', '+ ', '']) {\n    for (const v of ['sec', 'secs', 'second', 'seconds', 's']) {\n      t.is(secs(`${sign}1${v}`), 1)\n      t.is(secs(`${sign}1 ${v}`), 1)\n    }\n    for (const v of ['minute', 'minutes', 'min', 'mins', 'm']) {\n      t.is(secs(`${sign}1${v}`), 60)\n      t.is(secs(`${sign}1 ${v}`), 60)\n    }\n    for (const v of ['hour', 'hours', 'hr', 'hrs', 'h']) {\n      t.is(secs(`${sign}1${v}`), 3600)\n      t.is(secs(`${sign}1 ${v}`), 3600)\n    }\n    for (const v of ['day', 'days', 'd']) {\n      t.is(secs(`${sign}1${v}`), 86400)\n      t.is(secs(`${sign}1 ${v}`), 86400)\n    }\n    for (const v of ['week', 'weeks', 'w']) {\n      t.is(secs(`${sign}1${v}`), 604800)\n      t.is(secs(`${sign}1 ${v}`), 604800)\n    }\n    for (const v of ['years', 'year', 'yrs', 'yr', 'y']) {\n      t.is(secs(`${sign}1${v}`), 31557600)\n      t.is(secs(`${sign}1 ${v}`), 31557600)\n    }\n  }\n\n  for (const sign of ['-', '- ']) {\n    for (const v of ['sec', 'secs', 'second', 'seconds', 's']) {\n      t.is(secs(`${sign}1${v}`), -1)\n      t.is(secs(`${sign}1 ${v}`), -1)\n    }\n    for (const v of ['minute', 'minutes', 'min', 'mins', 'm']) {\n      t.is(secs(`${sign}1${v}`), -60)\n      t.is(secs(`${sign}1 ${v}`), -60)\n    }\n    for (const v of ['hour', 'hours', 'hr', 'hrs', 'h']) {\n      t.is(secs(`${sign}1${v}`), -3600)\n      t.is(secs(`${sign}1 ${v}`), -3600)\n    }\n    for (const v of ['day', 'days', 'd']) {\n      t.is(secs(`${sign}1${v}`), -86400)\n      t.is(secs(`${sign}1 ${v}`), -86400)\n    }\n    for (const v of ['week', 'weeks', 'w']) {\n      t.is(secs(`${sign}1${v}`), -604800)\n      t.is(secs(`${sign}1 ${v}`), -604800)\n    }\n    for (const v of ['years', 'year', 'yrs', 'yr', 'y']) {\n      t.is(secs(`${sign}1${v}`), -31557600)\n      t.is(secs(`${sign}1 ${v}`), -31557600)\n    }\n  }\n\n  for (const v of ['sec', 'secs', 'second', 'seconds', 's']) {\n    t.is(secs(`1${v} ago`), -1)\n    t.is(secs(`1${v} from now`), 1)\n    t.is(secs(`1 ${v} ago`), -1)\n    t.is(secs(`1 ${v} from now`), 1)\n  }\n  for (const v of ['minute', 'minutes', 'min', 'mins', 'm']) {\n    t.is(secs(`1${v} ago`), -60)\n    t.is(secs(`1${v} from now`), 60)\n    t.is(secs(`1 ${v} ago`), -60)\n    t.is(secs(`1 ${v} from now`), 60)\n  }\n  for (const v of ['hour', 'hours', 'hr', 'hrs', 'h']) {\n    t.is(secs(`1${v} ago`), -3600)\n    t.is(secs(`1${v} from now`), 3600)\n    t.is(secs(`1 ${v} ago`), -3600)\n    t.is(secs(`1 ${v} from now`), 3600)\n  }\n  for (const v of ['day', 'days', 'd']) {\n    t.is(secs(`1${v} ago`), -86400)\n    t.is(secs(`1${v} from now`), 86400)\n    t.is(secs(`1 ${v} ago`), -86400)\n    t.is(secs(`1 ${v} from now`), 86400)\n  }\n  for (const v of ['week', 'weeks', 'w']) {\n    t.is(secs(`1${v} ago`), -604800)\n    t.is(secs(`1${v} from now`), 604800)\n    t.is(secs(`1 ${v} ago`), -604800)\n    t.is(secs(`1 ${v} from now`), 604800)\n  }\n  for (const v of ['years', 'year', 'yrs', 'yr', 'y']) {\n    t.is(secs(`1${v} ago`), -31557600)\n    t.is(secs(`1${v} from now`), 31557600)\n    t.is(secs(`1 ${v} ago`), -31557600)\n    t.is(secs(`1 ${v} from now`), 31557600)\n  }\n\n  t.throws(() => secs('1 fortnight'), {\n    instanceOf: TypeError,\n    message: 'Invalid time period format',\n  })\n\n  t.throws(() => secs('= 1 second'), {\n    instanceOf: TypeError,\n    message: 'Invalid time period format',\n  })\n\n  t.throws(() => secs('- 1 second ago'), {\n    instanceOf: TypeError,\n    message: 'Invalid time period format',\n  })\n})\n"
  },
  {
    "path": "test/util/decode_jwt.test.ts",
    "content": "import test from 'ava'\n\nimport { decodeJwt, errors, base64url } from '../../src/index.js'\n\ntest('invalid inputs', (t) => {\n  const jwt =\n    'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'\n\n  const parts = jwt.split('.')\n\n  t.throws(() => decodeJwt(null as any), {\n    instanceOf: errors.JWTInvalid,\n    message: 'JWTs must use Compact JWS serialization, JWT must be a string',\n  })\n\n  t.throws(() => decodeJwt('....'), {\n    instanceOf: errors.JWTInvalid,\n    message: 'Only JWTs using Compact JWS serialization can be decoded',\n  })\n\n  t.throws(() => decodeJwt('.'), {\n    instanceOf: errors.JWTInvalid,\n    message: 'Invalid JWT',\n  })\n\n  t.throws(() => decodeJwt([parts[0], '', parts[2]].join('.')), {\n    instanceOf: errors.JWTInvalid,\n    message: 'JWTs must contain a payload',\n  })\n\n  t.throws(() => decodeJwt([parts[0], base64url.encode('null'), parts[2]].join('.')), {\n    instanceOf: errors.JWTInvalid,\n    message: 'Invalid JWT Claims Set',\n  })\n\n  t.throws(() => decodeJwt([parts[0], base64url.encode('[]'), parts[2]].join('.')), {\n    instanceOf: errors.JWTInvalid,\n    message: 'Invalid JWT Claims Set',\n  })\n\n  t.throws(() => decodeJwt([parts[0], base64url.encode('{\"notajson'), parts[2]].join('.')), {\n    instanceOf: errors.JWTInvalid,\n    message: 'Failed to parse the decoded payload as JSON',\n  })\n\n  t.deepEqual(decodeJwt([parts[0], base64url.encode('{}'), parts[2]].join('.')), {})\n\n  t.deepEqual(decodeJwt(jwt), {\n    sub: '1234567890',\n    name: 'John Doe',\n    iat: 1516239022,\n  })\n})\n"
  },
  {
    "path": "test/util/decode_protected_header.test.ts",
    "content": "import test from 'ava'\n\nimport { decodeProtectedHeader } from '../../src/index.js'\n\ntest('invalid inputs', (t) => {\n  t.throws(() => decodeProtectedHeader(null), {\n    instanceOf: TypeError,\n    message: 'Invalid Token or Protected Header formatting',\n  })\n\n  t.throws(() => decodeProtectedHeader('.'), {\n    instanceOf: TypeError,\n    message: 'Invalid Token or Protected Header formatting',\n  })\n\n  t.throws(() => decodeProtectedHeader('ew..'), {\n    instanceOf: TypeError,\n    message: 'Invalid Token or Protected Header formatting',\n  })\n\n  t.throws(() => decodeProtectedHeader('bnVsbA..'), {\n    instanceOf: TypeError,\n    message: 'Invalid Token or Protected Header formatting',\n  })\n\n  t.throws(() => decodeProtectedHeader('W10..'), {\n    instanceOf: TypeError,\n    message: 'Invalid Token or Protected Header formatting',\n  })\n\n  t.throws(() => decodeProtectedHeader('...'), {\n    instanceOf: TypeError,\n    message: 'Invalid Token or Protected Header formatting',\n  })\n\n  t.throws(() => decodeProtectedHeader('ew....'), {\n    instanceOf: TypeError,\n    message: 'Invalid Token or Protected Header formatting',\n  })\n\n  t.throws(() => decodeProtectedHeader('bnVsbA....'), {\n    instanceOf: TypeError,\n    message: 'Invalid Token or Protected Header formatting',\n  })\n\n  t.throws(() => decodeProtectedHeader('W10....'), {\n    instanceOf: TypeError,\n    message: 'Invalid Token or Protected Header formatting',\n  })\n\n  t.throws(() => decodeProtectedHeader('.....'), {\n    instanceOf: TypeError,\n    message: 'Invalid Token or Protected Header formatting',\n  })\n\n  t.throws(() => decodeProtectedHeader({ protected: null }), {\n    instanceOf: TypeError,\n    message: 'Invalid Token or Protected Header formatting',\n  })\n\n  t.throws(() => decodeProtectedHeader({ protected: 'ew' }), {\n    instanceOf: TypeError,\n    message: 'Invalid Token or Protected Header formatting',\n  })\n\n  t.throws(() => decodeProtectedHeader({ protected: 'bnVsbA' }), {\n    instanceOf: TypeError,\n    message: 'Invalid Token or Protected Header formatting',\n  })\n\n  t.throws(() => decodeProtectedHeader({ protected: 'W10' }), {\n    instanceOf: TypeError,\n    message: 'Invalid Token or Protected Header formatting',\n  })\n\n  t.throws(() => decodeProtectedHeader({}), {\n    instanceOf: TypeError,\n    message: 'Token does not contain a Protected Header',\n  })\n\n  t.deepEqual(decodeProtectedHeader('eyJhbGciOiJIUzI1NiJ9..'), { alg: 'HS256' })\n  t.deepEqual(decodeProtectedHeader('eyJhbGciOiJIUzI1NiJ9....'), { alg: 'HS256' })\n  t.deepEqual(decodeProtectedHeader({ protected: 'eyJhbGciOiJIUzI1NiJ9' }), { alg: 'HS256' })\n})\n"
  },
  {
    "path": "tools/postbump.cjs",
    "content": "const { x } = require('tar')\nconst { globSync } = require('glob')\n\nconst { execSync } = require('child_process')\nconst { readFileSync, writeFileSync } = require('fs')\nconst { version } = require('../package.json')\n\nconst readme = readFileSync('docs/README.md')\nconst tagName = `v${version}`\nconst opts = { stdio: 'inherit' }\n\ntry {\n  execSync('git rm -f docs/**/*.md', opts)\n} catch {}\nexecSync('find docs -type d | grep \"docs/\" | xargs rm -rf', opts)\nexecSync('npx patch-package', opts)\nexecSync(`npm run docs:generate -- --gitRevision ${tagName}`, opts)\nglobSync('docs/**/*.md').forEach((file) => {\n  const content = readFileSync(file, 'utf-8')\n  const updatedContent = content.replaceAll('\\\\<`ArrayBufferLike`\\\\>', '')\n\n  writeFileSync(file, updatedContent, 'utf-8')\n})\nwriteFileSync('docs/README.md', readme)\nexecSync('npm pack', opts)\nexecSync('rm -rf dist', opts)\nx({\n  f: `jose-${version}.tgz`,\n  strip: true,\n  filter(loc) {\n    return loc.startsWith('package/dist/')\n  },\n  sync: true,\n})\nexecSync('npm run build:deno', opts)\nwriteFileSync(\n  'dist/deno/README.md',\n  readFileSync('docs/readme.md', { encoding: 'utf-8' })\n    .replace(/^`jose` is distributed.+$\\n\\n/m, '')\n    .replace(\n      /\\*\\*[\\s\\S]+```/gm,\n      `**\\`example\\`** Deno import\n\\`\\`\\`js\nimport * as jose from 'https://deno.land/x/jose@${tagName}/index.ts'\n\\`\\`\\``,\n    )\n    .replace(/(\\]\\()(?!https)/gm, `](https://github.com/panva/jose/blob/${tagName}/docs/`),\n)\nexecSync('npm run build:bundle', opts)\nexecSync('npm run build:bundle-min', opts)\nexecSync('npm run build:umd', opts)\nexecSync('git add docs/**/*.md', opts)\n\nconst filesToUpdate = [\n  { path: './README.md', regex: /jose@v\\d+\\.\\d+\\.\\d+/gm, replacement: `jose@v${version}` },\n  { path: './docs/README.md', regex: /jose@v\\d+\\.\\d+\\.\\d+/gm, replacement: `jose@v${version}` },\n  {\n    path: './jsr.json',\n    regex: /\"version\": \"\\d+\\.\\d+\\.\\d+\"/gm,\n    replacement: `\"version\": \"${version}\"`,\n  },\n]\n\nfilesToUpdate.forEach(({ path, regex, replacement }) => {\n  writeFileSync(path, readFileSync(path, { encoding: 'utf-8' }).replace(regex, replacement))\n  execSync(`git add ${path}`, { stdio: 'inherit' })\n})\n\nconst ts = globSync('dist/**/**.ts')\n\nfunction filterExamples(file) {\n  let inExample = false\n  return file\n    .split('\\n')\n    .filter((line) => {\n      let remove = inExample\n      if (line.includes('* @example')) {\n        remove = inExample = true\n      } else if (line.includes('```') && !line.includes('```js')) {\n        inExample = false\n      } else if (inExample) {\n        remove = true\n      }\n      return remove === false\n    })\n    .join('\\n')\n}\n\nfunction trimExcessComment(file) {\n  let previousWasEmpty = false\n  return file\n    .split('\\n')\n    .filter((line) => {\n      let remove = false\n      if (line.trim() === '*' && previousWasEmpty) {\n        remove = true\n      } else if (line.trim() === '*' || line.trim() === '/**') {\n        previousWasEmpty = true\n      } else {\n        previousWasEmpty = false\n      }\n\n      return remove === false\n    })\n    .join('\\n')\n}\n\nfor (const file of ts) {\n  writeFileSync(file, trimExcessComment(filterExamples(readFileSync(file, { encoding: 'utf-8' }))))\n}\n\nfor (const dir of ['types', 'deno', 'webapi']) {\n  execSync(`git add dist/${dir} -f`, opts)\n}\n"
  },
  {
    "path": "tools/prebump.cjs",
    "content": "const { execSync } = require('child_process')\nconst { readFileSync, writeFileSync } = require('fs')\n\nconst dryRun = execSync('standard-version --dry-run', { encoding: 'utf-8' })\n;/tagging release v(\\d+\\.\\d+\\.\\d+)/gm.test(dryRun)\n\nconst version = RegExp.$1\nconst tagName = `v${version}`\n\nconst path = './src/jwks/remote.ts'\nwriteFileSync(path, readFileSync(path, { encoding: 'utf-8' }).replace(/v(\\d+\\.\\d+\\.\\d+)/g, tagName))\nexecSync(`git add ${path}`, { stdio: 'inherit' })\n"
  },
  {
    "path": "tools/publish.cjs",
    "content": "const { readFileSync, writeFileSync, unlinkSync } = require('fs')\n\nconst pkg = JSON.parse(readFileSync('./package.json'))\npkg.devDependencies = undefined\npkg.scripts = undefined\npkg.imports = undefined\n\nwriteFileSync('./package.json', `${JSON.stringify(pkg, null, 2)}\\n`)\nunlinkSync('./CHANGELOG.md')\n"
  },
  {
    "path": "tools/release-notes.cjs",
    "content": "const fs = require('fs')\nconst { execSync } = require('child_process')\n\nexecSync('git show HEAD -- CHANGELOG.md > CHANGELOG.diff')\n\nconst tag = execSync('git tag --points-at HEAD').toString().trim()\n\nfs.writeFileSync(\n  'notes.md',\n  fs\n    .readFileSync('CHANGELOG.diff')\n    .toString()\n    .split('\\n')\n    .filter((line) => line.startsWith('+') && !line.startsWith('+++'))\n    .map((line) => line.slice(1))\n    .slice(3)\n    .join('\\n'),\n)\n\nexecSync(`gh release create ${tag} -F notes.md --title ${tag} --discussion-category Releases`)\n"
  },
  {
    "path": "tsconfig/types.json",
    "content": "{\n  \"extends\": \"../tsconfig.json\",\n  \"compilerOptions\": {\n    \"target\": \"ESNext\",\n    \"outDir\": \"../dist/types\",\n    \"declaration\": true,\n    \"emitDeclarationOnly\": true,\n    \"removeComments\": false\n  }\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"files\": [\"./src/index.ts\"],\n  \"compilerOptions\": {\n    \"outDir\": \"./dist/webapi\",\n    \"target\": \"ES2022\",\n    \"module\": \"ES2022\",\n    \"lib\": [\"ES2022\", \"DOM\", \"DOM.Iterable\"],\n    \"types\": [],\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"sourceMap\": false,\n    \"removeComments\": true,\n    \"verbatimModuleSyntax\": true,\n    \"erasableSyntaxOnly\": true\n  }\n}\n"
  },
  {
    "path": "typedoc.json",
    "content": "{\n  \"$schema\": \"https://typedoc.org/schema.json\",\n  \"disableSources\": true,\n  \"hideBreadcrumbs\": true,\n  \"entryPoints\": [\n    \"src/types.d.ts\",\n    \"src/jwe/**/*.ts\",\n    \"src/jwk/*.ts\",\n    \"src/jwks/*.ts\",\n    \"src/jws/**/*.ts\",\n    \"src/jwt/*.ts\",\n    \"src/key/*.ts\",\n    \"src/util/*.ts\",\n  ],\n  \"excludeExternals\": true,\n  \"excludePrivate\": true,\n  \"excludeProtected\": true,\n  \"gitRevision\": \"main\",\n  \"hideGenerator\": true,\n  \"out\": \"docs\",\n  \"plugin\": [\"typedoc-plugin-markdown\", \"typedoc-plugin-mdn-links\"],\n  \"readme\": \"none\",\n  \"sort\": [\"kind\", \"static-first\", \"required-first\", \"alphabetical\"],\n  \"githubPages\": false,\n  \"parametersFormat\": \"table\",\n  \"pageTitleTemplates\": {\n    \"member\": \"{keyword} {kind}: {name}\\n\\n## [💗 Help the project](https://github.com/sponsors/panva)\\n\\nSupport from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).\"\n  },\n  \"hidePageHeader\": true\n}\n"
  }
]