Skip to content

Release: share-URL validation + dependabot deploy hardening#61

Merged
Itroun merged 8 commits intomainfrom
staging
Apr 23, 2026
Merged

Release: share-URL validation + dependabot deploy hardening#61
Itroun merged 8 commits intomainfrom
staging

Conversation

@Itroun
Copy link
Copy Markdown
Contributor

@Itroun Itroun commented Apr 23, 2026

Promotes staging to production.

Changes since last release

Test plan

  • Unit tests: 193/193 pass on staging CI
  • Staging smoke checks: valid share URL loads, tampered share URL (non-hex color payload) rejected with expected user-facing error
  • Post-deploy smoke check on production

dependabot Bot and others added 8 commits April 13, 2026 09:37
Bumps the patch-updates group with 2 updates: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) and [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).


Updates `vite` from 8.0.4 to 8.0.8
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.8/packages/vite)

Updates `vitest` from 4.1.2 to 4.1.4
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.4/packages/vitest)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: vitest
  dependency-version: 4.1.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…mitation

GITHUB_TOKEN merges don't trigger other workflows, so deploy-production.yml
never fires after dependabot PRs are merged to main. The dependabot deploy
workflow now builds and deploys to Cloudflare Pages directly after merging,
and syncs main back into staging. Also adds workflow_dispatch to
deploy-production.yml for manual triggers.
…oup (#55)

Bumps the patch-updates group with 1 update: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `vite` from 8.0.8 to 8.0.9
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.9/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [happy-dom](https://github.com/capricorn86/happy-dom) from 20.8.9 to 20.9.0.
- [Release notes](https://github.com/capricorn86/happy-dom/releases)
- [Commits](capricorn86/happy-dom@v20.8.9...v20.9.0)

---
updated-dependencies:
- dependency-name: happy-dom
  dependency-version: 20.9.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Back-to-back dependabot PRs landing on staging could race the
dependabot-deploy workflow: the second staging→main PR would enable
`gh pr merge --auto`, which silently no-ops when no required check is
pending, leaving the PR stuck and the workflow timing out.

Three defenses:
- Group minor updates alongside patches so a typical week produces one
  combined PR instead of several.
- Try an immediate squash merge first and only fall back to --auto when
  the PR isn't yet mergeable, so --auto's no-op behavior can't strand
  a ready PR.
- Add a concurrency group so overlapping deploy runs queue instead of
  racing each other.
`validateShareData` previously only checked `version === 1` and the
truthiness of `grid`/`colors`, so a crafted share URL could set
`patternColors` to arbitrary strings. Those strings flow into
`exportSvg` as `fill="${color}"` via string concatenation, so a payload
like `"/><script>...</script>` in a downloaded SVG would execute when
the victim opens the file directly in a browser.

Strict-validate share data at the boundary: hex-regex each color in
`colors.pattern`, `colors.background`, and `palette.custom`; require
plain objects and finite numeric dimensions; require array-of-arrays
shape for cells. Also run `sanitizeGrid` on share-URL cells to match
the file-import path (export.js:817). Promoted `sanitizeGrid` to an
exported helper.
@Itroun Itroun merged commit 1665445 into main Apr 23, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant