From 49c3e2c9057d132253a4d4db4d2b77ce2ef414e6 Mon Sep 17 00:00:00 2001 From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Date: Sun, 7 Jun 2026 09:03:28 -0700 Subject: [PATCH 01/11] feat: add ignore_https_errors input for self-signed certificates Opt-in input that sets Playwright's ignoreHTTPSErrors on the browser context so the scanner can run against staging hosts with self-signed or invalid certs. Default off; behavior unchanged unless enabled. Closes #150 Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/actions/find/README.md | 4 ++ .github/actions/find/action.yml | 4 ++ .github/actions/find/src/findForUrl.ts | 2 + .github/actions/find/src/index.ts | 14 +++- .github/actions/find/tests/findForUrl.test.ts | 69 +++++++++++++++---- README.md | 2 + action.yml | 5 ++ 7 files changed, 84 insertions(+), 16 deletions(-) diff --git a/.github/actions/find/README.md b/.github/actions/find/README.md index b8bca81c..7549e98b 100644 --- a/.github/actions/find/README.md +++ b/.github/actions/find/README.md @@ -31,6 +31,10 @@ configuration option. [`colorScheme`](https://playwright.dev/docs/api/class-browser#browser-new-context-option-color-scheme) configuration option. +#### `ignore_https_errors` + +**Optional** Bool - whether to ignore HTTPS errors when scanning URLs with self-signed certificates. + #### `include_screenshots` **Optional** Bool - whether to capture screenshots of scanned pages and include links to them in the issue diff --git a/.github/actions/find/action.yml b/.github/actions/find/action.yml index fb53d901..d93bc02b 100644 --- a/.github/actions/find/action.yml +++ b/.github/actions/find/action.yml @@ -25,6 +25,10 @@ inputs: color_scheme: description: 'Playwright colorScheme setting: https://playwright.dev/docs/api/class-browser#browser-new-context-option-color-scheme' required: false + ignore_https_errors: + description: 'Whether to ignore HTTPS errors when scanning URLs with self-signed certificates' + required: false + default: 'false' outputs: findings_file: diff --git a/.github/actions/find/src/findForUrl.ts b/.github/actions/find/src/findForUrl.ts index d9f1ea87..a8928417 100644 --- a/.github/actions/find/src/findForUrl.ts +++ b/.github/actions/find/src/findForUrl.ts @@ -13,6 +13,7 @@ export async function findForUrl( includeScreenshots: boolean = false, reducedMotion?: ReducedMotionPreference, colorScheme?: ColorSchemePreference, + ignoreHttpsErrors: boolean = false, ): Promise { const {url, excludeSelectors} = urlConfig const browser = await playwright.chromium.launch({ @@ -23,6 +24,7 @@ export async function findForUrl( ...(authContext?.toPlaywrightBrowserContextOptions() ?? {}), ...(reducedMotion ? {reducedMotion} : {}), ...(colorScheme ? {colorScheme} : {}), + ...(ignoreHttpsErrors ? {ignoreHTTPSErrors: true} : {}), } const context = await browser.newContext(contextOptions) const page = await context.newPage() diff --git a/.github/actions/find/src/index.ts b/.github/actions/find/src/index.ts index 675dff6f..0b647d57 100644 --- a/.github/actions/find/src/index.ts +++ b/.github/actions/find/src/index.ts @@ -11,6 +11,7 @@ export default async function () { const urls = loadUrls({urlConfigs}) const reducedMotion = loadReducedMotion() const colorScheme = loadColorScheme() + const ignoreHttpsErrors = loadIgnoreHttpsErrors() const actualUrls = urlConfigs || urls || [] @@ -22,7 +23,14 @@ export default async function () { for (const urlConfig of actualUrls) { const {url} = urlConfig core.info(`Preparing to scan ${url}`) - const findingsForUrl = await findForUrl(urlConfig, authContext, includeScreenshots, reducedMotion, colorScheme) + const findingsForUrl = await findForUrl( + urlConfig, + authContext, + includeScreenshots, + reducedMotion, + colorScheme, + ignoreHttpsErrors, + ) if (findingsForUrl.length === 0) { core.info(`No accessibility gaps were found on ${url}`) continue @@ -101,3 +109,7 @@ function loadColorScheme() { return colorSchemeInput as ColorSchemePreference } + +function loadIgnoreHttpsErrors() { + return core.getInput('ignore_https_errors', {required: false}).toLowerCase() === 'true' +} diff --git a/.github/actions/find/tests/findForUrl.test.ts b/.github/actions/find/tests/findForUrl.test.ts index 85299c5c..dfeb0039 100644 --- a/.github/actions/find/tests/findForUrl.test.ts +++ b/.github/actions/find/tests/findForUrl.test.ts @@ -7,21 +7,29 @@ import * as pluginManager from '../src/pluginManager/index.js' import type {Plugin} from '../src/pluginManager/types.js' import {clearCache} from '../src/scansContextProvider.js' +const playwrightMocks = vi.hoisted(() => { + const page = { + pageUrl: '', + goto: vi.fn(), + url: vi.fn(), + } + const context = { + newPage: vi.fn(() => page), + close: vi.fn(), + } + const browser = { + newContext: vi.fn(() => context), + close: vi.fn(), + } + + return {browser, context, page} +}) + vi.mock('@actions/core', {spy: true}) vi.mock('playwright', () => ({ default: { chromium: { - launch: () => ({ - newContext: () => ({ - newPage: () => ({ - pageUrl: '', - goto: () => {}, - url: () => {}, - }), - close: () => {}, - }), - close: () => {}, - }), + launch: vi.fn(() => playwrightMocks.browser), }, }, })) @@ -49,7 +57,7 @@ describe('findForUrl', () => { async function axeOnlyTest() { clearAll() - await findForUrl('test.com') + await findForUrl({url: 'test.com'}) expect(AxeBuilder.prototype.analyze).toHaveBeenCalledTimes(1) expect(pluginManager.loadPlugins).toHaveBeenCalledTimes(0) expect(pluginManager.invokePlugin).toHaveBeenCalledTimes(0) @@ -80,7 +88,7 @@ describe('findForUrl', () => { actionInput = JSON.stringify(['axe', 'custom-scan-1']) clearAll() - await findForUrl('test.com') + await findForUrl({url: 'test.com'}) expect(AxeBuilder.prototype.analyze).toHaveBeenCalledTimes(1) expect(pluginManager.loadPlugins).toHaveBeenCalledTimes(1) expect(pluginManager.invokePlugin).toHaveBeenCalledTimes(1) @@ -97,7 +105,7 @@ describe('findForUrl', () => { actionInput = JSON.stringify(['custom-scan-1', 'custom-scan-2']) clearAll() - await findForUrl('test.com') + await findForUrl({url: 'test.com'}) expect(AxeBuilder.prototype.analyze).toHaveBeenCalledTimes(0) expect(pluginManager.loadPlugins).toHaveBeenCalledTimes(1) expect(pluginManager.invokePlugin).toHaveBeenCalledTimes(2) @@ -112,9 +120,40 @@ describe('findForUrl', () => { actionInput = JSON.stringify(['custom-scan-1']) clearAll() - await findForUrl('test.com') + await findForUrl({url: 'test.com'}) expect(loadedPlugins[0].default).toHaveBeenCalledTimes(1) expect(loadedPlugins[1].default).toHaveBeenCalledTimes(0) }) }) + + describe('when ignoreHttpsErrors is enabled', () => { + it('forwards ignoreHTTPSErrors to the browser context', async () => { + actionInput = '' + clearAll() + + await findForUrl({url: 'test.com'}, undefined, false, undefined, undefined, true) + + expect(playwrightMocks.browser.newContext).toHaveBeenCalledWith({ignoreHTTPSErrors: true}) + }) + }) + + describe('when ignoreHttpsErrors is not enabled', () => { + it('does not forward ignoreHTTPSErrors by default', async () => { + actionInput = '' + clearAll() + + await findForUrl({url: 'test.com'}) + + expect(playwrightMocks.browser.newContext).toHaveBeenCalledWith({}) + }) + + it('does not forward ignoreHTTPSErrors when explicitly disabled', async () => { + actionInput = '' + clearAll() + + await findForUrl({url: 'test.com'}, undefined, false, undefined, undefined, false) + + expect(playwrightMocks.browser.newContext).toHaveBeenCalledWith({}) + }) + }) }) diff --git a/README.md b/README.md index 88b68c11..133eeb31 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ jobs: # open_grouped_issues: false # Optional: Set to true to open an issue grouping individual issues per violation # reduced_motion: no-preference # Optional: Playwright reduced motion configuration option # color_scheme: light # Optional: Playwright color scheme configuration option + # ignore_https_errors: false # Optional: Set to true to ignore HTTPS errors when scanning URLs with self-signed certificates # scans: '["axe","reflow-scan"]' # Optional: An array of scans (or plugins) to be performed. If not provided, only Axe will be performed. # url_configs: '[{"url":"https://example.com","excludeSelectors":["iframe","#widget"]}]' # Optional: Per-URL config with CSS selectors to exclude from the Axe scan. When provided, takes precedence over 'urls'. ``` @@ -130,6 +131,7 @@ Trigger the workflow manually or automatically based on your configuration. The | `open_grouped_issues` | No | Whether to create a tracking issue which groups filed issues together by violation type. Default: `false` | `true` | | `reduced_motion` | No | Playwright `reducedMotion` setting for scan contexts. Allowed values: `reduce`, `no-preference` | `reduce` | | `color_scheme` | No | Playwright `colorScheme` setting for scan contexts. Allowed values: `light`, `dark`, `no-preference` | `dark` | +| `ignore_https_errors` | No | Whether to ignore HTTPS errors when scanning URLs with self-signed certificates. Default: `false` | `true` | | `scans` | No | An array of scans (or plugins) to be performed. If not provided, only Axe will be performed. | `'["axe", "reflow-scan", ...other plugins]'` | | `url_configs` | No | A stringified JSON array of URL config objects. Each object must have a `url` field and may have an optional `excludeSelectors` field (array of CSS selectors to exclude from the Axe scan for that URL). When provided, takes precedence over the `urls` input. | `'[{"url":"https://example.com","excludeSelectors":["iframe","#widget"]}]'` | diff --git a/action.yml b/action.yml index b86a45e5..44343444 100644 --- a/action.yml +++ b/action.yml @@ -51,6 +51,10 @@ inputs: color_scheme: description: 'Playwright colorScheme setting: https://playwright.dev/docs/api/class-browser#browser-new-context-option-color-scheme' required: false + ignore_https_errors: + description: 'Whether to ignore HTTPS errors when scanning URLs with self-signed certificates' + required: false + default: 'false' scans: description: 'Stringified JSON array of scans to perform. If not provided, only Axe will be performed' required: false @@ -117,6 +121,7 @@ runs: include_screenshots: ${{ inputs.include_screenshots }} reduced_motion: ${{ inputs.reduced_motion }} color_scheme: ${{ inputs.color_scheme }} + ignore_https_errors: ${{ inputs.ignore_https_errors }} scans: ${{ inputs.scans }} - name: File id: file From 0060cc352060060e155088197561642723ed6784 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2026 20:03:43 +0000 Subject: [PATCH 02/11] chore(deps): Bump the github-actions group across 1 directory with 2 updates Bumps the github-actions group with 2 updates in the / directory: [actions/setup-node](https://github.com/actions/setup-node) and [ruby/setup-ruby](https://github.com/ruby/setup-ruby). Updates `actions/setup-node` from 7.0.0 to 7.1.0 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/820762786026740c76f36085b0efc47a31fe5020...949feb2413d6458794dcd2491c4babbbce0c15c1) Updates `ruby/setup-ruby` from 1.327.0 to 1.328.0 - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/14594264cd68ce8a2345dd349bc3d138a4ef85c8...e81a8fa391b11a595c1b7ed84177cc0fe02faf83) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: 7.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions - dependency-name: ruby/setup-ruby dependency-version: 1.328.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] --- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 446e8c84..a880f2b3 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -26,7 +26,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Node - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 with: node-version: 24 cache: npm diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f90a8505..82293f96 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Ruby - uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 + uses: ruby/setup-ruby@e81a8fa391b11a595c1b7ed84177cc0fe02faf83 with: ruby-version: '3.4' bundler-cache: true From 6d84bfe49d5d5b0f6c9b50cf55279f534b27e0b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 13:46:24 -0700 Subject: [PATCH 03/11] chore(deps-dev): Bump vite from 8.2.2 to 8.3.5 (#286) Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.2.2 to 8.3.5.
Release notes

Sourced from vite's releases.

v8.3.5

Bug Fixes

  • build: handle missing chunk import maps (#23777) (8d7623d)
  • build: include preload dependencies to chunk import map hashing (#23793) (4d16e7c)
  • bundled-dev: apply server.origin to asset URLs (#23683) (52ba877)
  • bundled-dev: declare utf-8 charset in fallback page (#23846) (197daf6)
  • bundled-dev: ignore build.chunkImportMap (#23685) (cfe917d)
  • bundled-dev: include user import.meta.env.* defines in the import.meta.env object (#23713) (6019aa7)
  • bundled-dev: map forwarded error stacks through the bundle source maps (#23741) (11fe1e4)
  • bundled-dev: normalize served output files (#23684) (df4e02c)
  • bundled-dev: stop hmr propagation at modules that are no longer imported (#23839) (7471e8c)
  • css: don't fail on a literal % in url() (#23676) (50b382d)
  • deps: update all non-major dependencies (#23731) (cf80aa5)
  • deps: update all non-major dependencies (#23826) (77d8373)
  • deps: update rolldown-related dependencies (#23733) (43f0d05)
  • deps: update rolldown-related dependencies (#23827) (c2e0418)
  • optimizer: fall back to yarn.lock for lockfile hash (#23667) (f206096)
  • optimizer: scan oxc.jsxInject imports (#23758) (38f3cb4)
  • optimizer: skip patches dir check for yarn.lock fallback (#23725) (8e890e1)
  • optimizer: skip patches dir hash for nub lockfile (#23761) (a7d5696)
  • resolve: support subpath imports with multiple # (#23631) (0d86b34)
  • resolve: update resolve.exports to 2.0.4 (#23739) (4ea708a)
  • server: handle socket errors on upgrade requests not taken by the HMR server (#23728) (c2c9ef4)
  • server: only strip base when path matches a full segment (#23641) (3dfde87)

Performance Improvements

  • ssr: extract inline source maps without a regexp (#23775) (6a02780)

Miscellaneous Chores

Code Refactoring

  • deps: replace @vercel/detect-agent with std-env (#23744) (ce4293f)
  • dev: consolidate moduleURL to file path utilities (#23828) (df7b40e)
  • dev: separate import resolution from URL conversion (#23791) (6116689)
  • dev: share ModuleURL and BrowserURL conversions (#23790) (446954c)
  • dev: use ModuleURLs throughout HTML transforms (#23815) (a162990)

v8.3.4

Features

  • bundled-dev: support import.meta.hot.acceptExports (#23463) (bc0f21c)

Bug Fixes

... (truncated)

Changelog

Sourced from vite's changelog.

8.3.5 (2026-10-21)

Bug Fixes

  • build: handle missing chunk import maps (#23777) (8d7623d)
  • build: include preload dependencies to chunk import map hashing (#23793) (4d16e7c)
  • bundled-dev: apply server.origin to asset URLs (#23683) (52ba877)
  • bundled-dev: declare utf-8 charset in fallback page (#23846) (197daf6)
  • bundled-dev: ignore build.chunkImportMap (#23685) (cfe917d)
  • bundled-dev: include user import.meta.env.* defines in the import.meta.env object (#23713) (6019aa7)
  • bundled-dev: map forwarded error stacks through the bundle source maps (#23741) (11fe1e4)
  • bundled-dev: normalize served output files (#23684) (df4e02c)
  • bundled-dev: stop hmr propagation at modules that are no longer imported (#23839) (7471e8c)
  • css: don't fail on a literal % in url() (#23676) (50b382d)
  • deps: update all non-major dependencies (#23731) (cf80aa5)
  • deps: update all non-major dependencies (#23826) (77d8373)
  • deps: update rolldown-related dependencies (#23733) (43f0d05)
  • deps: update rolldown-related dependencies (#23827) (c2e0418)
  • optimizer: fall back to yarn.lock for lockfile hash (#23667) (f206096)
  • optimizer: scan oxc.jsxInject imports (#23758) (38f3cb4)
  • optimizer: skip patches dir check for yarn.lock fallback (#23725) (8e890e1)
  • optimizer: skip patches dir hash for nub lockfile (#23761) (a7d5696)
  • resolve: support subpath imports with multiple # (#23631) (0d86b34)
  • resolve: update resolve.exports to 2.0.4 (#23739) (4ea708a)
  • server: handle socket errors on upgrade requests not taken by the HMR server (#23728) (c2c9ef4)
  • server: only strip base when path matches a full segment (#23641) (3dfde87)

Performance Improvements

  • ssr: extract inline source maps without a regexp (#23775) (6a02780)

Miscellaneous Chores

Code Refactoring

  • deps: replace @vercel/detect-agent with std-env (#23744) (ce4293f)
  • dev: consolidate moduleURL to file path utilities (#23828) (df7b40e)
  • dev: separate import resolution from URL conversion (#23791) (6116689)
  • dev: share ModuleURL and BrowserURL conversions (#23790) (446954c)
  • dev: use ModuleURLs throughout HTML transforms (#23815) (a162990)

8.3.4 (2026-10-08)

Features

  • bundled-dev: support import.meta.hot.acceptExports (#23463) (bc0f21c)

Bug Fixes

... (truncated)

Commits
  • 981f07f release: v8.3.5 (#23856)
  • 0d86b34 fix(resolve): support subpath imports with multiple # (#23631)
  • 6a02780 perf(ssr): extract inline source maps without a regexp (#23775)
  • 8e890e1 fix(optimizer): skip patches dir check for yarn.lock fallback (#23725)
  • 197daf6 fix(bundled-dev): declare utf-8 charset in fallback page (#23846)
  • 4d16e7c fix(build): include preload dependencies to chunk import map hashing (#23793)
  • df7b40e refactor(dev): consolidate moduleURL to file path utilities (#23828)
  • a162990 refactor(dev): use ModuleURLs throughout HTML transforms (#23815)
  • 6116689 refactor(dev): separate import resolution from URL conversion (#23791)
  • 446954c refactor(dev): share ModuleURL and BrowserURL conversions (#23790)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=vite&package-manager=npm_and_yarn&previous-version=8.2.2&new-version=8.3.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/github/accessibility-scanner/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 164 +++++++++++++++++++++++----------------------- 1 file changed, 82 insertions(+), 82 deletions(-) diff --git a/package-lock.json b/package-lock.json index bf4c2478..c30d1d86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -480,9 +480,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.148.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.148.0.tgz", - "integrity": "sha512-Nm4s/jB+4FpFsPhWGEC4h7rzksesmtnMXomo6rCMcg/b8zLQuOziRgkCS1fxDCXOlJB/6Q8oABOZ/OP6RIPj9A==", + "version": "0.154.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.154.0.tgz", + "integrity": "sha512-KYOUGQFlLWR+s4QMV2Q9ko38TZm7EdO87Qm7rvZLqk/webse/cDjtyxKhg/47l0byCbs/k46LT8qc4PKjAikzA==", "dev": true, "license": "MIT", "peer": true, @@ -491,9 +491,9 @@ } }, "node_modules/@rolldown/binding-android-arm-eabi": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.7.tgz", - "integrity": "sha512-EypzgnYCwyVY4NDHKzGmNJT5b+XaQEBniHxsMdeIQLB/tcCzZnhqrzHpZFbX9iaxx+5RiB8caATBtfvZP7zVxQ==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.14.tgz", + "integrity": "sha512-aWR+XKH9+rW7m5fWq/5360J3mHycrx/o6xZM2DQFdJnTMdyP7/WzxPjhtLbVWdKo2y612/4U1bWqb3HQhiF7vg==", "cpu": [ "arm" ], @@ -509,9 +509,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.7.tgz", - "integrity": "sha512-l17HE9EweWaqJZhuUuNBN/FzM62xw+DECVnJyvMsxn8vJFAGLy5QfLDoYAcronkAN8VxKZHezDpulHDPx95vFw==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.14.tgz", + "integrity": "sha512-QiVxHofl6A8lQU7WAtOUY4QMVZXohxwz7WJJoeh8NBEUyKfIkMRKhYyq8az/1RypNiIXzNTtiS6KwHz0erxYRQ==", "cpu": [ "arm64" ], @@ -527,9 +527,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.7.tgz", - "integrity": "sha512-8ED8ELFvHXc6OCETIn4gXObPiaR6bckM/ipXtbzlPVDRMBfEGjCKgO90F9YtfdpDatVx/ZQw7aZ1vUMf/+T3Mw==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.14.tgz", + "integrity": "sha512-lTQOzHuBIooh3jIr5XINQkjPGEuGy+Dsy0meXDr6Sjty0b99kYgGh4uBC/8mJX1T0kC8d6S0aPP1Y+bHkh6aBw==", "cpu": [ "arm64" ], @@ -545,9 +545,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.7.tgz", - "integrity": "sha512-/WPripjtiAIZ2tWY7ddijORT0Ujg87wxWW/qcoFVCKAWVDPhtY0xr7Dj0M3GyNGz60jGwTElhro/mkF9dT7dDQ==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.14.tgz", + "integrity": "sha512-hyMKEGatjmBYCs/Q4sbIcL/GqpFEqsX3wc+HYVQ/85A4rxc1o7rPm4DUI4GV4k/h0ITddwFSGpqQunI14GXjTA==", "cpu": [ "x64" ], @@ -563,9 +563,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.7.tgz", - "integrity": "sha512-14DI4NcqpvbICxSnGLx3PmtDaWqRP/KGSGb6C+JLLVPeZRl6dKdHba3pGsqT3vpdTqhEYIPG0MMQ8c0xYqoJxA==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.14.tgz", + "integrity": "sha512-u371GbXoVXrEgP20PwzoGNOdAOqAMhzo19JzzY+V4YmmnC+DTOoqdbMu+O+54emM59Mik/UdrtWgcuEDKWRPKA==", "cpu": [ "x64" ], @@ -581,9 +581,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.7.tgz", - "integrity": "sha512-bxrWIRvHWQvbJwi+VIie/kDJmQxcNE6xxWwZdqF/ExVAigtHkv54WTLQPb+QsZdnFy18fg7JPfWGL0RH6vwIlQ==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.14.tgz", + "integrity": "sha512-BqwKsdZQf6EqVWr8fv2MrDYzAvOZ7+NYFSJESRGs87fkseEhs0TU9TXgRJTkZoRRkxTizyEg1LKUXfU3/78uqg==", "cpu": [ "arm" ], @@ -599,9 +599,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.7.tgz", - "integrity": "sha512-toOY2BChBZyuxU7OYX6Tn389di4IzAqPTycVcci0O7FSfBqzRB3RZn+K5Is6ANf4tmgRd/K1yZTsNTXbkXsnLg==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.14.tgz", + "integrity": "sha512-SD9kY8M009x/7s57Z1dgUVlP5+uYBgKQK0Tkr1WIWngrtUJmRCW1RJFMY7QDla2khXhmg2i5Io7MUjcmZNZ/KQ==", "cpu": [ "arm64" ], @@ -620,9 +620,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.7.tgz", - "integrity": "sha512-lAIXTH/aiLRLxsTgQvfhjo4K1ydWIp00+V0voOr9beb/9ZmkUFrSIb03dXNFRgMNvkE6oGsF10ioQ6UsI+vS5Q==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.14.tgz", + "integrity": "sha512-BJ2CL19M6uuWesMgnqJzgxoI+N+eV7b0A9O9vLV42y+gitC41fNa8KElau1tHVzuLWX5GzEuxMPhAO0tQXQMkg==", "cpu": [ "arm64" ], @@ -641,9 +641,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.7.tgz", - "integrity": "sha512-kdnwS28Pkenp/mZMRwjXXXwxQ7pIsm+bF919LUK93BOyhcLsrVKdP2p9fxpiPNPAbNuch8ypQt0pm2P2LYCAGg==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.14.tgz", + "integrity": "sha512-4+Kl8daPV8NDHaD7mfCcc1pRM+Qg7ab8DyMm5FG5WoZgv4h2i3KFN1CybYBNbQqmuYm7ftJLvmMI1eHYJ22S/Q==", "cpu": [ "ppc64" ], @@ -662,9 +662,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.7.tgz", - "integrity": "sha512-516OdsyLdr5E65paF3yBF55t8mfm9+gmtCsK3xI7XKXIT7EfRlHhxL8K/NR6Hu8BWSgF5+1w74lTL0+nxcc8Qw==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.14.tgz", + "integrity": "sha512-V/h8ePq1fKDrmtFMz6xcCN3DKvuvMRrwwD1q0PkBeeo4DpK64biaKvqWGVxqCeYKqeRk7gE7/iKPxLCn08O97A==", "cpu": [ "s390x" ], @@ -683,9 +683,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.7.tgz", - "integrity": "sha512-r8/z8n7GFaYRln3xmP1Cxy0HH/HLM0uBUPkEuSVEfKGDA89M0FsZRZJRSwe/tJjRx+fpH/gjorfhB8tmEbSFLA==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.14.tgz", + "integrity": "sha512-WxalXzgrLVpKC93xfpaJ3gCXUWzeCr+FRCbDVD2mUAy4L6Vo3lNVz0epUEUpxPWJkLNYUwM4OSIikv36OJ9mLg==", "cpu": [ "x64" ], @@ -704,9 +704,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.7.tgz", - "integrity": "sha512-pAsE8iiDxUg1xBqdhrTfg45AVDVpirjz00sblEYClGNNcMnDb+e8beQgqIAw6LvauX/APvgxUnwrgun/YYGBhw==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.14.tgz", + "integrity": "sha512-3G3tnAmTpdk9jO3GQtyHXqeFD2SlecfTws/Y3M2mmj9nMBwwuLT4kur8sZKeu7ENUHSpVO3cIsm5A52LEWWwlg==", "cpu": [ "x64" ], @@ -725,9 +725,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.7.tgz", - "integrity": "sha512-lTcIYmmnQQA8Or/2DatS6oSqcdLHvendjS+zLu+FwgToynWMRSmQdpM65fTANJgIS4mjbMOo5KT2lnT9SAb96w==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.14.tgz", + "integrity": "sha512-qyr5XiNGxm2ytx17vvtcJ9nXn6v1gENETi503bJx3OGwZ1tSonj7BosxbMa/xeAfSl5iS9X6KjEWYXLu6v1L7Q==", "cpu": [ "arm64" ], @@ -743,9 +743,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.7.tgz", - "integrity": "sha512-e3Gu3WxbNk/UqQhxqU7YIYO+9ZBvWNz3U+h/qRFosscMFzdRPbXYSaSWgSnklv2fz1TgzBTcti2z35c/7irsHw==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.14.tgz", + "integrity": "sha512-oA4o5o0S2yB199YyYXDzKUv1Z56Rc+mgOjwm7Z/vJ9Z8igiDPYvoOuDyo6g7AK/ZaF09nPhDKVnGBcYHO11GXA==", "cpu": [ "arm64" ], @@ -761,9 +761,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.7.tgz", - "integrity": "sha512-W/jg5qoRSqjsEv0+dZi4e687mcHqmVuU0P4fK6qS/xjetW2Gmc1W8j//z5nAeNcC8Ttm0hV46IjcYeuVwYhuiw==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.14.tgz", + "integrity": "sha512-9mE94bf2GZUaR/fUSXCMpBoWkctu421Mi0ORpm4zqfbkjKep7RxzPFa5etcGs5h+2KApoWBOA/hAJa/7saGgEQ==", "cpu": [ "x64" ], @@ -2025,9 +2025,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.18", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", - "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", "dev": true, "funding": [ { @@ -2157,9 +2157,9 @@ } }, "node_modules/postcss": { - "version": "8.5.28", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", - "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", + "version": "8.5.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.31.tgz", + "integrity": "sha512-YUbWYCgErwnMAVkjUnYa+KlMBzGpHwiIt/DE7f0G33AuX2LH9UcTk6KgWxd3zRU+pN3u/C+Xl3EnMLM4Hea7Sg==", "dev": true, "funding": [ { @@ -2178,9 +2178,9 @@ "license": "MIT", "peer": true, "dependencies": { - "nanoid": "^3.3.18", + "nanoid": "^3.3.20", "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "source-map-js": "^1.2.2" }, "engines": { "node": "^10 || ^12 || >=14" @@ -2223,14 +2223,14 @@ } }, "node_modules/rolldown": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.7.tgz", - "integrity": "sha512-g0EtLvBjTUB7jhyV0S/TCup3v/XSVl45vUIGbOGU4QPiyjTenCe4mKuFvW9fEgYmS2Fo42AUssRmNuMziXdrig==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.14.tgz", + "integrity": "sha512-eTBTTqMR6uHKLgcUqpJP8ntzDI6V4LYA8negAMBEI7gkgVvOdrx6VsvS2Ym+83KhOPdLCHWJu0w7UQFJZhHKNw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@oxc-project/types": "=0.148.0", + "@oxc-project/types": "=0.154.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -2240,21 +2240,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm-eabi": "1.2.7", - "@rolldown/binding-android-arm64": "1.2.7", - "@rolldown/binding-darwin-arm64": "1.2.7", - "@rolldown/binding-darwin-x64": "1.2.7", - "@rolldown/binding-freebsd-x64": "1.2.7", - "@rolldown/binding-linux-arm-gnueabihf": "1.2.7", - "@rolldown/binding-linux-arm64-gnu": "1.2.7", - "@rolldown/binding-linux-arm64-musl": "1.2.7", - "@rolldown/binding-linux-ppc64-gnu": "1.2.7", - "@rolldown/binding-linux-s390x-gnu": "1.2.7", - "@rolldown/binding-linux-x64-gnu": "1.2.7", - "@rolldown/binding-linux-x64-musl": "1.2.7", - "@rolldown/binding-openharmony-arm64": "1.2.7", - "@rolldown/binding-win32-arm64-msvc": "1.2.7", - "@rolldown/binding-win32-x64-msvc": "1.2.7" + "@rolldown/binding-android-arm-eabi": "1.2.14", + "@rolldown/binding-android-arm64": "1.2.14", + "@rolldown/binding-darwin-arm64": "1.2.14", + "@rolldown/binding-darwin-x64": "1.2.14", + "@rolldown/binding-freebsd-x64": "1.2.14", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.14", + "@rolldown/binding-linux-arm64-gnu": "1.2.14", + "@rolldown/binding-linux-arm64-musl": "1.2.14", + "@rolldown/binding-linux-ppc64-gnu": "1.2.14", + "@rolldown/binding-linux-s390x-gnu": "1.2.14", + "@rolldown/binding-linux-x64-gnu": "1.2.14", + "@rolldown/binding-linux-x64-musl": "1.2.14", + "@rolldown/binding-openharmony-arm64": "1.2.14", + "@rolldown/binding-win32-arm64-msvc": "1.2.14", + "@rolldown/binding-win32-x64-msvc": "1.2.14" } }, "node_modules/semver": { @@ -2472,17 +2472,17 @@ } }, "node_modules/vite": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz", - "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==", + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.5.tgz", + "integrity": "sha512-z1YpjieJ9g0ebTmQpLBv/oq9E3F9EIlOe+7LahW8SrE3LTiG3udBRUXQOlYXP9b+IC2q2phHeVxj9xGlw34OEQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { "lightningcss": "^1.33.0", - "picomatch": "^4.0.5", - "postcss": "^8.5.26", - "rolldown": "~1.2.4", + "picomatch": "^4.0.7", + "postcss": "^8.5.30", + "rolldown": "~1.2.14", "tinyglobby": "^0.2.17" }, "bin": { @@ -2499,7 +2499,7 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.4.0 || ^0.5.0", + "@vitejs/devtools": "^0.7.1 || ^0.8.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", From b5c9678148daa65be6a553e906158e3f9463e00f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 13:52:30 -0700 Subject: [PATCH 04/11] chore(deps-dev): Bump undici from 6.29.0 to 6.29.1 (#287) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [undici](https://github.com/nodejs/undici) from 6.29.0 to 6.29.1.
Release notes

Sourced from undici's releases.

v6.29.1

Security fixes

High severity

Denial of service via TLS 1.2 certificate-changing renegotiation

CVE-2026-87018 · GHSA-qrxm-fqhp-jwvm

A malicious or compromised HTTPS server could crash the Node.js process by initiating TLS 1.2 renegotiation and presenting a different, CA-trusted certificate whose hostname did not match the requested host. The resulting socket error reached an assertion in undici's HTTP/1.1 and HTTP/2 connection handling. This release handles post-connect certificate errors without terminating the process.

TLS certificate validation bypass through dropped Agent options

CVE-2026-109383 · GHSA-2m5v-pch6-74hx

Agent used a JSON-based clone for constructor options, which silently removed function-valued TLS options such as checkServerIdentity. Applications relying on custom certificate or public-key verification could therefore accept a certificate that the callback was intended to reject. This release preserves TLS options when creating per-origin dispatchers.

Denial of service through excessive Content-Encoding values

CVE-2026-109869 · GHSA-xjj6-f33q-929c

A malicious HTTP server could crash the Node.js process by returning more than five content codings and closing the connection before sending the body. Although fetch() rejected the response, an error from an orphaned internal stream could remain unhandled. This release validates the content-encoding chain before creating the body stream and aborts oversized chains safely.

Medium severity

Denial of service through unbounded EventSource parser state

CVE-2026-109924 · GHSA-4qv8-2p9j-2685

A malicious Server-Sent Events endpoint could exhaust process memory by sending many tiny data: fields without completing an event, or by splitting an unfinished line across many chunks. This release bounds retained EventSource parser state, including field counts, buffered chunks, unfinished-line length, and retained field data.

Denial of service through unbounded automatic WebSocket PONG buffering

CVE-2026-109932 · GHSA-9fm3-97px-rjf6

A malicious WebSocket server could exhaust process memory by flooding the client with PING frames while not reading the automatic PONG responses. undici previously ignored socket backpressure and allowed the outbound queue to grow without bound. This release pauses frame parsing when PONG writes encounter backpressure and resumes after the socket drains.

What's Changed

Full Changelog: https://github.com/nodejs/undici/compare/v6.29.0...v6.29.1

Commits
  • 8c57f6c [Release] v6.29.1 (#6023)
  • 39f93e1 fix(websocket): bound automatic PONG writes under backpressure
  • c43b23f fix(eventsource): bound retained SSE parser state
  • 1325a87 fix(fetch): abort excessive content encoding responses
  • 8c59f6b fix: preserve Agent connection options
  • b40fbfc fix: handle post-connect TLS certificate errors
  • 407630a [v6.x] fix(fetch): fix aborting Streams (#3754) (#6000)
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=undici&package-manager=npm_and_yarn&previous-version=6.29.0&new-version=6.29.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/github/accessibility-scanner/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kendall Gassner --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c30d1d86..25551af5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2438,9 +2438,9 @@ } }, "node_modules/undici": { - "version": "6.29.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.29.0.tgz", - "integrity": "sha512-R+RODBqp6i2pPflGdq+xIOUkl+RNfGgHwoinecKu/JCuf2uO06cOKoDbI2P7Dn6KcswdKwrczbU6IYJ6K8X+wg==", + "version": "6.29.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.29.1.tgz", + "integrity": "sha512-EvRlUt/QqAEvXdQeRMYUfwOQsfzpDztykrG2owGEE/rBOBoYv9uF39ZzsNDh4lTFHhTr2XOZjKkYgueD12ZmGA==", "dev": true, "license": "MIT", "engines": { From b37e9e1c6d2ea0ae918cb2c2b084d1b5c249710d Mon Sep 17 00:00:00 2001 From: Helen Hou-Sandi Date: Thu, 22 Oct 2026 23:44:13 -0400 Subject: [PATCH 05/11] Handle long accessibility rule labels Shorten rule labels beyond GitHub's 50-character limit with a deterministic hash suffix, and preserve the complete rule ID in the issue body. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5df06479-27fd-4edc-9e52-14ce2618d8d9 --- .github/actions/file/src/generateIssueBody.ts | 1 + .github/actions/file/src/openIssue.ts | 19 ++++++++++++- .../file/tests/generateIssueBody.test.ts | 14 ++++++++++ .github/actions/file/tests/openIssue.test.ts | 28 +++++++++++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/.github/actions/file/src/generateIssueBody.ts b/.github/actions/file/src/generateIssueBody.ts index ad703d51..b9f234af 100644 --- a/.github/actions/file/src/generateIssueBody.ts +++ b/.github/actions/file/src/generateIssueBody.ts @@ -52,6 +52,7 @@ ${standardsLine} const body = `${categoryNotice}## What ${describeFinding(finding)} +${finding.ruleId ? `**Rule:** \`${finding.scannerType} rule: ${finding.ruleId}\`\n\n` : ''} ${screenshotSection ?? ''} To fix this, ${finding.solutionShort}. ${solutionLong ? `\nSpecifically:\n\n${solutionLong}` : ''} diff --git a/.github/actions/file/src/openIssue.ts b/.github/actions/file/src/openIssue.ts index 67128d08..f22a4a35 100644 --- a/.github/actions/file/src/openIssue.ts +++ b/.github/actions/file/src/openIssue.ts @@ -1,11 +1,28 @@ import type {Octokit} from '@octokit/core' import type {Finding} from './types.d.js' import {generateIssueBody} from './generateIssueBody.js' +import {createHash} from 'node:crypto' import * as url from 'node:url' const URL = url.URL /** Max length for GitHub issue titles */ const GITHUB_ISSUE_TITLE_MAX_LENGTH = 256 +/** Max length for GitHub label names */ +const GITHUB_LABEL_NAME_MAX_LENGTH = 50 +const RULE_LABEL_HASH_LENGTH = 4 + +function createRuleLabel(scannerType: string, ruleId: string): string { + const label = `${scannerType} rule: ${ruleId}` + const characters = Array.from(label) + + if (characters.length <= GITHUB_LABEL_NAME_MAX_LENGTH) { + return label + } + + const hash = createHash('sha256').update(label).digest('hex').slice(0, RULE_LABEL_HASH_LENGTH) + const prefixLength = GITHUB_LABEL_NAME_MAX_LENGTH - hash.length - 1 + return `${characters.slice(0, prefixLength).join('')}-${hash}` +} /** * Truncates text to a maximum length, adding an ellipsis if truncated. @@ -25,7 +42,7 @@ export async function openIssue(octokit: Octokit, repoWithOwner: string, finding const labels = [`${primary.scannerType}-scanning-issue`] // Only include a ruleId label when it's defined if (primary.ruleId) { - labels.push(`${primary.scannerType} rule: ${primary.ruleId}`) + labels.push(createRuleLabel(primary.scannerType, primary.ruleId)) } // Flag non-WCAG findings so they can be filtered or triaged separately if (primary.category && primary.category !== 'wcag') { diff --git a/.github/actions/file/tests/generateIssueBody.test.ts b/.github/actions/file/tests/generateIssueBody.test.ts index 60a06db7..dfa78e64 100644 --- a/.github/actions/file/tests/generateIssueBody.test.ts +++ b/.github/actions/file/tests/generateIssueBody.test.ts @@ -24,12 +24,26 @@ describe('generateIssueBody', () => { const body = generateIssueBody(baseFinding, 'github/accessibility-scanner') expect(body).toContain('## What') + expect(body).toContain('**Rule:** `axe rule: color-contrast`') expect(body).toContain('## Acceptance Criteria') expect(body).toContain('The specific violation reported in this issue is no longer reproducible.') expect(body).toContain('The fix MUST meet WCAG 2.2 guidelines OR') expect(body).not.toContain('Specifically:') }) + it('omits the rule line when the finding has no ruleId', () => { + const body = generateIssueBody(findingWithEmptyOptionalFields, 'github/accessibility-scanner') + + expect(body).not.toContain('**Rule:**') + }) + + it('includes the full rule ID when its label would be shortened', () => { + const ruleId = 'keyboard-accessible/scrollable-region-with-an-extra-long-description' + const body = generateIssueBody({...baseFinding, ruleId}, 'github/accessibility-scanner') + + expect(body).toContain(`**Rule:** \`axe rule: ${ruleId}\``) + }) + it('formats solutionLong lines into bullets while preserving Fix any/Fix all lines', () => { const body = generateIssueBody( { diff --git a/.github/actions/file/tests/openIssue.test.ts b/.github/actions/file/tests/openIssue.test.ts index 890f8438..af4b54b4 100644 --- a/.github/actions/file/tests/openIssue.test.ts +++ b/.github/actions/file/tests/openIssue.test.ts @@ -1,4 +1,5 @@ import {describe, it, expect, vi} from 'vitest' +import {createHash} from 'node:crypto' // Mock generateIssueBody so we can inspect what screenshotRepo is passed vi.mock('../src/generateIssueBody.js', () => ({ @@ -65,6 +66,33 @@ describe('openIssue', () => { ) }) + it('shortens long rule labels with a deterministic hash suffix', async () => { + const octokit = mockOctokit() + const ruleId = 'keyboard-accessible/scrollable-region-with-an-extra-long-description' + const fullLabel = `axe rule: ${ruleId}` + await openIssue(octokit, 'org/repo', [{...baseFinding, ruleId}]) + + const labels = octokit.request.mock.calls[0][1].labels + const ruleLabel = labels[1] + const hash = createHash('sha256').update(fullLabel).digest('hex').slice(0, 4) + + expect(ruleLabel).toBe(`${fullLabel.slice(0, 45)}-${hash}`) + expect(Array.from(ruleLabel)).toHaveLength(50) + }) + + it('produces distinct labels for different long rule IDs', async () => { + const firstOctokit = mockOctokit() + const secondOctokit = mockOctokit() + const commonPrefix = 'keyboard-accessible/scrollable-region-with-a-long-description-' + await openIssue(firstOctokit, 'org/repo', [{...baseFinding, ruleId: `${commonPrefix}first`}]) + await openIssue(secondOctokit, 'org/repo', [{...baseFinding, ruleId: `${commonPrefix}second`}]) + + const firstLabel = firstOctokit.request.mock.calls[0][1].labels[1] + const secondLabel = secondOctokit.request.mock.calls[0][1].labels[1] + expect(firstLabel.slice(0, 45)).toBe(secondLabel.slice(0, 45)) + expect(firstLabel).not.toBe(secondLabel) + }) + it('adds a category label for non-WCAG findings', async () => { const octokit = mockOctokit() await openIssue(octokit, 'org/repo', [{...baseFinding, category: 'best-practice'}]) From 23fa5ee000f5f4b5e994fddeff5b2e73fb308ec6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Oct 2026 20:04:09 +0000 Subject: [PATCH 06/11] chore(deps): Bump ruby/setup-ruby Bumps the github-actions group with 1 update in the / directory: [ruby/setup-ruby](https://github.com/ruby/setup-ruby). Updates `ruby/setup-ruby` from 1.328.0 to 1.329.0 - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/e81a8fa391b11a595c1b7ed84177cc0fe02faf83...651ff0d62c5c79bed6d53ec518387aae20e72c1a) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.329.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 82293f96..0b2aa775 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Ruby - uses: ruby/setup-ruby@e81a8fa391b11a595c1b7ed84177cc0fe02faf83 + uses: ruby/setup-ruby@651ff0d62c5c79bed6d53ec518387aae20e72c1a with: ruby-version: '3.4' bundler-cache: true From d46305dcda4e0d4c79b4dc94076dae1c66efdfe3 Mon Sep 17 00:00:00 2001 From: Helen Hou-Sandi Date: Tue, 27 Oct 2026 15:38:52 -0400 Subject: [PATCH 07/11] Add accesslint to the list of scans in test workflow --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0b2aa775..e6294441 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -80,7 +80,7 @@ jobs: repository: ${{ env.TESTING_REPOSITORY }} token: ${{ secrets.GH_TOKEN }} cache_key: ${{ steps.cache_key.outputs.cache_key }} - scans: '["axe", "reflow-scan"]' + scans: '["axe", "reflow-scan", "accesslint"]' - name: Retrieve cached results uses: ./.github/actions/gh-cache/restore From 13fe126c3bd43468b1444c589e01dc143ac61b7c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Oct 2026 19:06:26 +0000 Subject: [PATCH 08/11] Update site test for AccessLint results Co-authored-by: helen <906334+helen@users.noreply.github.com> --- tests/site-with-errors.test.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/site-with-errors.test.ts b/tests/site-with-errors.test.ts index 59c66146..ec0003a9 100644 --- a/tests/site-with-errors.test.ts +++ b/tests/site-with-errors.test.ts @@ -128,12 +128,14 @@ describe('site-with-errors', () => { }, ] // Check that: - // - every expected object exists (no more and no fewer), and + // - every expected Axe and reflow-scan object exists (no more and no fewer), and // - each object has all fields, and // - field values match expectations exactly // A specific order is _not_ enforced. - expect(actual).toHaveLength(expected.length) - expect(actual).toEqual(expect.arrayContaining(expected)) + const actualWithoutAccesslint = actual.filter(({scannerType}) => scannerType !== 'accesslint') + expect(actualWithoutAccesslint).toHaveLength(expected.length) + expect(actualWithoutAccesslint).toEqual(expect.arrayContaining(expected)) + expect(actual.some(({scannerType}) => scannerType === 'accesslint')).toBe(true) }) it('GITHUB_TOKEN environment variable is set', () => { @@ -164,7 +166,9 @@ describe('site-with-errors', () => { }) it('issues exist and have expected title, state, and assignee', async () => { - const actualTitles = issues.map(({title}) => title) + const actualTitles = issues + .filter((_, index) => results[index].findings[0].scannerType !== 'accesslint') + .map(({title}) => title) const expectedTitles = [ 'Accessibility issue: Elements must meet minimum color contrast ratio thresholds on /', 'Accessibility issue: Page should contain a level-one heading on /', From d3018b063d12fd099e72fda941c52a4d21042367 Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Fri, 30 Oct 2026 00:20:41 -0700 Subject: [PATCH 09/11] fix: forward ignore_https_errors to auth and update find index test The built-in login flow ran in a browser context without ignoreHTTPSErrors, so login failed on self-signed hosts before Find could run. Auth now takes the same input and the root action passes it through. The find index test expects the new sixth argument. --- .github/actions/auth/README.md | 4 ++++ .github/actions/auth/action.yml | 4 ++++ .github/actions/auth/src/index.ts | 2 ++ .github/actions/find/tests/index.test.ts | 2 +- action.yml | 1 + 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/actions/auth/README.md b/.github/actions/auth/README.md index b857e0af..a9b96bea 100644 --- a/.github/actions/auth/README.md +++ b/.github/actions/auth/README.md @@ -21,6 +21,10 @@ Authenticate with Playwright and save session state. Supports HTTP Basic and for > [!IMPORTANT] > Don’t put passwords in your workflow as plain text; instead reference a [repository secret](https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets#creating-secrets-for-a-repository). +#### `ignore_https_errors` + +**Optional** Bool - whether to ignore HTTPS errors when logging in to hosts with self-signed certificates. + ### Outputs #### `auth_context` diff --git a/.github/actions/auth/action.yml b/.github/actions/auth/action.yml index c68b3331..fbf913cb 100644 --- a/.github/actions/auth/action.yml +++ b/.github/actions/auth/action.yml @@ -11,6 +11,10 @@ inputs: password: description: "Password" required: true + ignore_https_errors: + description: "Whether to ignore HTTPS errors when logging in to hosts with self-signed certificates" + required: false + default: "false" outputs: auth_context: diff --git a/.github/actions/auth/src/index.ts b/.github/actions/auth/src/index.ts index 68ff4e82..01f08eeb 100644 --- a/.github/actions/auth/src/index.ts +++ b/.github/actions/auth/src/index.ts @@ -15,6 +15,7 @@ export default async function () { const username = core.getInput('username', {required: true}) const password = core.getInput('password', {required: true}) core.setSecret(password) + const ignoreHttpsErrors = core.getInput('ignore_https_errors', {required: false}).toLowerCase() === 'true' // Launch a headless browser browser = await playwright.chromium.launch({ @@ -27,6 +28,7 @@ export default async function () { username, password, }, + ...(ignoreHttpsErrors ? {ignoreHTTPSErrors: true} : {}), }) page = await context.newPage() diff --git a/.github/actions/find/tests/index.test.ts b/.github/actions/find/tests/index.test.ts index f5d760fc..13cf72f8 100644 --- a/.github/actions/find/tests/index.test.ts +++ b/.github/actions/find/tests/index.test.ts @@ -43,7 +43,7 @@ describe('url_configs', () => { await find() - expect(mocks.findForUrl).toHaveBeenCalledWith(urlConfig, expect.anything(), false, undefined, undefined) + expect(mocks.findForUrl).toHaveBeenCalledWith(urlConfig, expect.anything(), false, undefined, undefined, false) }) it('rejects waitForSelectors values that are not arrays of strings', async () => { diff --git a/action.yml b/action.yml index 525d0213..8f305a3a 100644 --- a/action.yml +++ b/action.yml @@ -127,6 +127,7 @@ runs: login_url: ${{ inputs.login_url }} username: ${{ inputs.username }} password: ${{ inputs.password }} + ignore_https_errors: ${{ inputs.ignore_https_errors }} - name: Find id: find uses: ./../../_actions/github/accessibility-scanner/current/.github/actions/find From babe9022cef822932a882e9b780bf34210350d71 Mon Sep 17 00:00:00 2001 From: Abdul Ahmad Date: Fri, 30 Oct 2026 14:59:46 -0400 Subject: [PATCH 10/11] Update README with warning on HTTPS errors Added a warning about disabling TLS certificate validation when ignoring HTTPS errors in the README. --- .github/actions/auth/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/actions/auth/README.md b/.github/actions/auth/README.md index a9b96bea..a6fb9484 100644 --- a/.github/actions/auth/README.md +++ b/.github/actions/auth/README.md @@ -25,6 +25,11 @@ Authenticate with Playwright and save session state. Supports HTTP Basic and for **Optional** Bool - whether to ignore HTTPS errors when logging in to hosts with self-signed certificates. +[!WARNING] +Enabling this disables TLS certificate validation for the authentication step itself. If an attacker can intercept traffic, they can present an untrusted certificate and capture submitted credentials (including HTTP Basic auth and form passwords) and resulting session cookies/storage. + +Use this only in trusted test/staging environments. For shared workflows, prefer a separate explicit opt-in for auth flows (for example, `auth_ignore_https_errors`) so certificate checks are not unintentionally disabled during credentialed requests. + ### Outputs #### `auth_context` From 7425ccefd765cf8c01a6dbc59b7fa6b3273360ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Oct 2026 20:04:07 +0000 Subject: [PATCH 11/11] chore(deps): Bump ruby/setup-ruby Bumps the github-actions group with 1 update in the / directory: [ruby/setup-ruby](https://github.com/ruby/setup-ruby). Updates `ruby/setup-ruby` from 1.329.0 to 1.334.0 - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/651ff0d62c5c79bed6d53ec518387aae20e72c1a...26e5b7d197ebf60545ee9667bcbace0be11ccaec) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.334.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e6294441..6ca74608 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Ruby - uses: ruby/setup-ruby@651ff0d62c5c79bed6d53ec518387aae20e72c1a + uses: ruby/setup-ruby@26e5b7d197ebf60545ee9667bcbace0be11ccaec with: ruby-version: '3.4' bundler-cache: true