Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
version: 2
updates:
# npm dependencies of the pnpm workspace (root, packages/*, examples/*)
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
# Same supply-chain delay as pnpm's minimumReleaseAge
cooldown:
default-days: 3
groups:
prosemirror:
patterns: ['prosemirror-*']
dev-tooling:
dependency-type: development
update-types: [minor, patch]

# GitHub Actions (pinned by commit SHA)
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
cooldown:
default-days: 3
groups:
actions:
patterns: ['*']
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: CI

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
# pnpm version comes from the "packageManager" field of package.json
- uses: pnpm/action-setup@73e46992e05b19abd31f2f3c20e0e7370d762115 # v6.1.1
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: '24'
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm lint
# Build first: the react package and the example type-check against the built core
- run: pnpm build
- run: pnpm typecheck
# Fails on known vulnerabilities in the dependencies shipped to users
- name: Audit production dependencies
run: pnpm audit --prod
35 changes: 21 additions & 14 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,34 @@ on:
branches: [main]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write
permissions: {}

concurrency:
group: pages
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
env:
GITHUB_PAGES: true
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
version: 8
- uses: actions/setup-node@v4
persist-credentials: false
# pnpm version comes from the "packageManager" field of package.json
- uses: pnpm/action-setup@73e46992e05b19abd31f2f3c20e0e7370d762115 # v6.1.1
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: '20'
node-version: '24'
cache: 'pnpm'
- run: pnpm install
- run: pnpm --filter @labbs/openblock-core build && pnpm --filter @labbs/openblock-react build
- run: pnpm install --frozen-lockfile
- run: pnpm --filter "./packages/*" build
- run: pnpm --filter @labbs/openblock-example-basic build
- uses: actions/configure-pages@v4
- uses: actions/upload-pages-artifact@v3
- uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
- uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: './examples/basic/dist'

Expand All @@ -38,6 +42,9 @@ jobs:
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
permissions:
pages: write
id-token: write
steps:
- uses: actions/deploy-pages@v4
- uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
id: deployment
102 changes: 67 additions & 35 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,62 +1,94 @@
name: Publish to GitHub Packages
name: Publish

# Runs when a GitHub Release is published (tag vX.Y.Z or vX.Y.Z-prerelease):
# 1. publishes @labbs/openblock-core and @labbs/openblock-react to GitHub Packages
# 2. attaches the ready-to-use builds to the Release:
# - standalone browser bundles (openblock-core.esm.js / .iife.js, openblock-react.esm.js)
# - openblock.css
# - the npm tarballs (installable with `npm install <asset URL>`, no registry token needed)
# - SHA256SUMS.txt

on:
release:
types: [published]

permissions: {}

concurrency:
group: publish-${{ github.event.release.tag_name }}
cancel-in-progress: false

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
contents: write # upload release assets
packages: write # publish to GitHub Packages
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v2
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
version: 8
persist-credentials: false

# pnpm version comes from the "packageManager" field of package.json
- uses: pnpm/action-setup@73e46992e05b19abd31f2f3c20e0e7370d762115 # v6.1.1

- uses: actions/setup-node@v4
# No dependency cache in the release job (avoids cache poisoning)
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: '20'
cache: 'pnpm'
node-version: '24'
registry-url: 'https://npm.pkg.github.com'
scope: '@labbs'
package-manager-cache: false

- name: Extract version from tag
- name: Extract and validate version from tag
id: version
env:
TAG: ${{ github.event.release.tag_name }}
run: |
# Remove 'v' prefix from tag (v1.0.0-beta2 -> 1.0.0-beta2)
VERSION=${GITHUB_REF_NAME#v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Publishing version: $VERSION"
VERSION="${TAG#v}"
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
echo "::error::Tag '$TAG' is not a valid version (expected vX.Y.Z or vX.Y.Z-prerelease)"
exit 1
fi
# Pre-releases (1.2.0-beta.1) are published under the "next" dist-tag
if [[ "$VERSION" == *-* ]]; then DIST_TAG=next; else DIST_TAG=latest; fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "dist_tag=$DIST_TAG" >> "$GITHUB_OUTPUT"
echo "Publishing version $VERSION (dist-tag: $DIST_TAG)"

- name: Update package versions
- run: pnpm install --frozen-lockfile

# `workspace:*` dependencies are rewritten to the exact version by `pnpm publish`
- name: Set package versions
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
VERSION=${{ steps.version.outputs.version }}
# Update core package version
cd packages/core
npm pkg set version="$VERSION"
cd ../react
# Update react package version
npm pkg set version="$VERSION"
# Update dependency on core to use exact version
npm pkg set dependencies.@labbs/openblock-core="$VERSION"

- run: pnpm install --no-frozen-lockfile
for pkg in packages/core packages/react; do
(cd "$pkg" && npm pkg set version="$VERSION")
done

- name: Build packages
run: |
pnpm --filter @labbs/openblock-core build
pnpm --filter @labbs/openblock-react build
run: pnpm --filter "./packages/*" build

- name: Publish @labbs/openblock-core
run: pnpm --filter @labbs/openblock-core publish --access public --no-git-checks
- name: Publish to GitHub Packages
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DIST_TAG: ${{ steps.version.outputs.dist_tag }}
run: pnpm --filter "./packages/*" publish --access public --no-git-checks --tag "$DIST_TAG"

- name: Publish @labbs/openblock-react
run: pnpm --filter @labbs/openblock-react publish --access public --no-git-checks
- name: Prepare release assets
run: |
mkdir -p release
pnpm --filter "./packages/*" pack --pack-destination "$PWD/release"
cp packages/core/dist/standalone/openblock-core.esm.js* release/
cp packages/core/dist/standalone/openblock-core.iife.js* release/
cp packages/react/dist/standalone/openblock-react.esm.js* release/
cp packages/core/dist/styles/editor.css release/openblock.css
(cd release && sha256sum -- * > SHA256SUMS.txt)
ls -la release

- name: Upload assets to the GitHub Release
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ github.token }}
TAG: ${{ github.event.release.tag_name }}
run: gh release upload "$TAG" release/* --clobber --repo "$GITHUB_REPOSITORY"
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,38 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Security
- **prosemirror-view upgraded to 1.42.9** — fixes an XSS in paste handling (GHSA, affected `< 1.42.3`).
- **CSS injection** — style-bearing attributes (`textColor` / `backgroundColor` marks, `textAlign`, table cell
`colwidth` / `backgroundColor`, column `width`, columnList `gap`, image `width` / `alignment`, heading `level`) are
now validated in both `parseDOM` and `toDOM`. Values arriving through JSON, Y.js collaboration or raw `data-*`
attributes in pasted HTML can no longer inject arbitrary CSS (e.g. tracking `background-image: url(...)` or
full-page `position: fixed` overlays).
- **Embed sandbox** — generic embeds pointing at the host page's own origin no longer get `allow-same-origin`
(combined with `allow-scripts` it lets a same-origin page escape the iframe sandbox).
- `editor.setLink()` ignores unsafe hrefs (`javascript:`…) instead of storing them in the document.
- React `LinkPopover`: "open link" validates the href before calling `window.open`.

### Added
- **CommonJS builds** (`require('@labbs/openblock-core')`) alongside ESM, with bundled `.d.ts` / `.d.cts` declarations.
- **Standalone browser bundles**: `openblock-core.iife.js` (`window.OpenBlock`), `openblock-core.esm.js`,
`openblock-react.esm.js` — exported as `@labbs/openblock-core/standalone`, `@labbs/openblock-core/standalone/iife`
and `@labbs/openblock-react/standalone`.
- Release workflow attaches the npm tarballs, standalone bundles, `openblock.css` and `SHA256SUMS.txt` to each
GitHub Release; pre-release tags publish under the `next` dist-tag.
- Public sanitization helpers: `sanitizeLinkHref`, `sanitizeImageSrc`, `sanitizeEmbedUrl`, `sanitizeCssColor`,
`sanitizeTextAlign`, `toNonNegativeNumber`, and `generateId`.
- CI workflow (lint, build, type-check, production dependency audit) and Dependabot configuration.

### Changed
- Removed the `uuid` runtime dependency (block IDs use the Web Crypto API).
- React peer dependency is now `^18.0.0 || ^19.0.0`; ref props accept React 19 `RefObject<T | null>`.
- `main` now points to the CommonJS build (`module` / `exports.import` still resolve to ESM).
- Tooling: Vite 8, vite-plugin-dts 5, TypeScript 6.0, ESLint 10, pnpm 10 (pinned via `packageManager`),
Node.js 24 in CI; GitHub Actions pinned by commit SHA.

## [1.0.0] - 2026-01-25

### Added
Expand Down
Loading
Loading