# Unreleased ### Breaking changes - **Node 25 is now the default development and CI target.** `packageManager` is now `pnpm@11.1.2` and `engines.pnpm` requires `>=11.1.2`. Node 25 [stopped shipping Corepack](https://github.com/nodejs/node/pull/57617); install pnpm directly with `npm install -g pnpm` (or follow the existing `bin/installer.sh` one-liner, which does this for you). ### Notable enhancements - **Privacy — drop swagger-ui telemetry, document phone-homes, add opt-outs.** - Dropped `swagger-ui-express` because upstream injects a Scarf analytics pixel that cannot be disabled at install or runtime (see [swagger-api/swagger-ui#10573](https://github.com/swagger-api/swagger-ui/issues/10573)). `/api-docs` now serves a vendored copy of [Scalar](https://github.com/scalar/scalar) (MIT) configured with `withDefaultFonts: false` and `telemetry: false` so no outbound calls are made. - New `privacy.updateCheck` (default `true`) — set to `false` to disable the hourly `UpdateCheck.ts` request to `${updateServer}/info.json`. - New `privacy.pluginCatalog` (default `true`) — set to `false` to disable the admin plugins page fetch of `${updateServer}/plugins.json`. CLI install-by-name still works. - New [`PRIVACY.md`](PRIVACY.md) at repo root documenting both outbound calls, what they send, and how to turn each off. - `bin/plugins/stalePlugins.ts` now reads `settings.updateServer` (was hardcoded to `static.etherpad.org`) and honours the new flag. - Closes #7524. - **Self-update subsystem — Tier 2 (manual click).** - Admins on a git install can click "Apply update" at `/admin/update`. Etherpad runs a 60s session drain (with T-60 / T-30 / T-10 broadcasts to every pad), `git fetch / checkout / pnpm install --frozen-lockfile / pnpm run build:ui`, and exits with code 75 so a process supervisor restarts it on the new version. The next boot runs a 60s health check; if `/health` doesn't come up the previous SHA + lockfile are restored automatically. - Crash-loop guard: if the new version reboots more than twice without the health check completing, RollbackHandler forces a rollback regardless of the timer. - Terminal `rollback-failed` state surfaces a strong banner; the admin clicks Acknowledge once they've manually recovered to clear the lock and re-allow Tier 2 attempts. - New settings under `updates.*`: `preApplyGraceMinutes`, `drainSeconds`, `rollbackHealthCheckSeconds`, `diskSpaceMinMB`, `requireSignature`, `trustedKeysPath`. Tag signature verification is opt-in (default `false`) — see `doc/admin/updates.md` for the keyring setup. - **A process supervisor (systemd / pm2 / docker `--restart=unless-stopped`) is required to apply updates.** Without one, exit 75 leaves the instance down. - **Self-update subsystem — Tier 3 (auto with grace window).** - On a git install, set `updates.tier: "auto"` to have new releases applied automatically after `preApplyGraceMinutes`. During the grace window, `/admin/update` shows a live countdown plus Cancel and Apply now buttons. Schedules are persisted to `var/update-state.json`, so an Etherpad restart during the grace window rehydrates the timer instead of losing the schedule. A new release tag detected mid-grace re-arms the timer; if `adminEmail` is set, a one-shot `grace-start` notification fires per scheduled tag (issue #7607). - The terminal `rollback-failed` state continues to disable auto/autonomous attempts globally until acknowledged; manual click stays available because an admin click *is* the intervention the terminal state requires. - Tier 4 (autonomous in a maintenance window) remains designed but unimplemented and will land in a subsequent release. # 2.7.3 ### Breaking changes - **Minimum required Node.js version is now 22.13.** Node.js 20 is reaching end-of-life (see https://nodejs.org/en/about/previous-releases) and pnpm 11 hard-rejects Node releases older than 22.13. The CI matrix targets Node 22, 24, and 25. Upgrading should be straightforward — install a current Node.js release before updating Etherpad. - **The official Docker image no longer ships `curl`, `npm`, or `npx`.** These were dropped to remove transitive CVEs (curl/libcurl SMB advisories, npm's bundled picomatch 4.0.3 and brace-expansion 2.0.2). The container's healthcheck now uses `wget` (busybox built-in, always present), and Etherpad provisions `pnpm` via `corepack` for all runtime package operations. If you exec into the container and rely on `curl` or `npm` for ad-hoc tasks, install them on demand with `apk add curl` or use the busybox `wget` / `pnpm` already present. ### Notable enhancements - **GDPR / privacy controls.** A multi-PR series adds the building blocks operators need to satisfy data-subject requests: - Pad deletion controls (admin-driven and self-service). - IP / privacy audit pass across the codebase. - Author-token cookies are now `HttpOnly`, removing them from JavaScript reach. - Configurable privacy banner shown on first visit. - Author erasure: an authenticated path for purging an individual author's identity and contributions. - **Self-update subsystem (Tier 1: notify).** - Periodic check against the GitHub Releases API for the configured repo (default `ether/etherpad`). Configurable via the new `updates.*` settings block, default tier `"notify"`. Set `updates.tier` to `"off"` to disable entirely. - The admin UI shows a banner and a dedicated "Etherpad updates" page with the current version, latest version, install method, and changelog. - Pad users see a discreet footer badge **only** when the running version is severely outdated (one or more major versions behind) or flagged as vulnerable in a recent release manifest. The public endpoint that drives this never leaks the version string itself. - New top-level `adminEmail` setting. When set, the updater emails the admin on first detection of severe / vulnerable status, with escalating cadence (weekly while vulnerable, monthly while severely outdated). PR 1 ships the dedupe + cadence logic; real SMTP wiring lands in a follow-up PR. - Tier 1 ships in this release. Tiers 2 (manual click), 3 (auto with grace window) and 4 (autonomous in maintenance window) are designed and will land in subsequent releases. - See `doc/admin/updates.md` for full configuration. - **Pad compaction.** New `compactPad` HTTP API plus `bin/compactPad` and `bin/compactAllPads` CLIs to reclaim database space on long-lived pads with heavy edit history (issue #6194). `--keep N` retains the last N revisions; `--dry-run` previews per-pad rev counts before writing. Per-pad failures don't stop the bulk run. - `bin/compactStalePads` (issue #7642) targets only pads not edited in the last `--older-than N` days, so hot pads in active timeslider use are left alone. Same `--keep` / `--dry-run` shape as `bin/compactAllPads`. Targeting is deliberately a CLI concern — the `compactPad` API surface stays unchanged. - **New packaging targets.** - Etherpad is now published as a **Snap** package. - **Debian (.deb)** packages are built via nfpm with a systemd unit, and a signed apt repository is published to `etherpad.org/apt`. - **Editor enhancements.** - IDE-style line operations: keyboard shortcuts to duplicate or delete the current line. - New `showMenuRight` URL parameter to hide the right-side toolbar — useful for embeds that need slimmer chrome. - Click a user in the userlist to open chat with `@` prefilled, making mentions discoverable. - New `padOptions.fadeInactiveAuthorColors` setting plus a toolbar UI to fade the background colors of authors who have left the pad. - **Color contrast.** Author colors now pick the WCAG-higher-contrast text color for readability. - **Social / mobile metadata.** Pad, timeslider, and home views now emit Open Graph and Twitter Card tags (closes #7599) and a `theme-color` meta that matches the toolbar on mobile. - **Plugin admin UX.** The `/admin` plugin browser surfaces each plugin's `ep.json` `disables` declarations, so operators can see what a plugin will turn off before installing. ### Notable fixes - **Socket.io: don't kick authenticated duplicate-author sessions.** A regression where two tabs from the same authenticated author could evict each other has been fixed (#7656 / #7678). - **Anchor scrolling.** Anchor-link navigation now waits for layout to settle, so jumping to a deep link no longer overshoots. - **Plugin updater.** `bin/updatePlugins.sh` actually updates installed plugins again (closes #6670). - **Settings: stable per-release version string.** `randomVersionString` is now derived from the release identity rather than regenerated on each boot, so caches behave correctly across restarts of the same version. ### Internal / contributor-facing - The HTTP client in the backend has been migrated from `axios` to the built-in `fetch` API, dropping a dependency now that Node 22 ships a stable fetch. - `admin/` and `ui/` workspaces moved from `rolldown-vite` to upstream **Vite 8**. - Build and CI moved to **pnpm 11** (`packageManager: "pnpm@11.1.2"`); the `Dockerfile`, snap, and all GitHub workflows are aligned. pnpm overrides have been migrated from `package.json` to `pnpm-workspace.yaml` to match pnpm 11's expectations. - All client modules have been converted to ESM. - The CI matrix tests Node 22, 24, and 25; on PRs the matrix is reduced to a single Node version to keep feedback fast. - Frontend Playwright tests now run against the `/ether` plugin set, with feature-tag based skips so plugin-incompatible specs are excluded automatically. - Build hardening: signed apt repo publishing, frozen lockfile installs across CI, Node setup pinned in every workflow, and a Docker-image CVE sweep that bumps `npm`, `pnpm`, and `uuid`. ### Localisation - Multiple updates from translatewiki.net. # 2.7.2 ### Notable enhancements and fixes - Accessibility pass: corrected dialog semantics, improved focus management, added missing icon labels, and set the `html lang` attribute correctly. - Chat: clicking the chat icon works again, disabled toggles render properly, and the username layout no longer overflows. - `/export/etherpad` now honors the `:rev` URL segment, so revision-specific exports return the requested revision instead of the latest. - Undo / redo now scrolls the viewport to follow the caret, so reverted edits stay in view. - Page Down / Page Up now scrolls by viewport height instead of a fixed line count, matching standard editor behavior on tall and short windows alike. - Editbar: caret is restored to the pad after changing a toolbar select, so typing continues in the document instead of falling through to the toolbar. - Admin: i18n is restored on `/admin` so the admin UI is translated again. # 2.7.1 ### Notable enhancements and fixes - fixed stop harcoding lang=en, letting the client auto detect locale - Stop mutating the shared plugin registry during sanitization - Preserve non-breaking space # 2.7.0 ### Breaking changes - **Abiword has been replaced with LibreOffice for document import/export.** If you were using Abiword for DOCX/ODT/PDF conversion, update your `settings.json` to point `soffice` at your LibreOffice binary. DOCX export is now supported out of the box. ### Notable enhancements - Added line numbers to the timeslider so you can follow along with specific lines while replaying a pad's history. - Added a playback speed setting to the timeslider — you can now scrub through history faster (or slower) than real time. - Creator-owned pad settings defaults: the user who creates a pad now seeds its default settings, giving pad creators more control over initial configuration. - Cookie names are now configurable via a prefix setting. Useful when running multiple Etherpads on the same domain and you need to keep their session cookies from colliding. - Added a new `aceRegisterLineAttributes` hook so plugins can preserve custom line attributes across Enter / line-split operations. Documentation for the hook is included. - Added a one-line installer script for getting Etherpad running quickly on a fresh machine. - Docker images are now published to GitHub Container Registry (GHCR) in addition to Docker Hub. - npm publishing of core and plugins has been migrated to OIDC trusted publishing for stronger supply-chain security. ### Notable fixes - Database drivers are now bundled with Etherpad again, so fresh installs no longer fail to connect to Postgres, MySQL, and friends out of the box. A regression test has been added to prevent this from breaking again. - Pending changesets are now flushed immediately after a reconnect instead of being silently dropped, and users are warned when a pending edit is not accepted by the server. - Head revision and atext are now captured atomically, preventing the occasional "mismatched apply" errors on busy pads. - Clearing authorship colors can now be undone without forcing a client disconnect. - Added periodic cleanup of expired/stale sessions from the database, and fixed a race condition in the session cleanup timeout. - Error messages returned to clients are now sanitized by default with deduplication, so internal details no longer leak through error responses. - Raised the maximum socket.io message size to 10 MB so large pastes no longer get rejected. - Dev mode entrypoint paths now respect the `x-proxy-path` header, fixing reverse-proxy setups in development. - Numerous list-related fixes: numbered list wrapped lines now indent correctly, ordered list numbering is preserved across bullet interruptions during export, consecutive numbering survives indented sub-bullets, switching from unordered to ordered resets numbering, and line attributes are preserved across drag-and-drop. - Bold (and other) formatting is now retained after copy-paste. - Dead-key / compose-key input no longer eats the preceding space. - `POST` API requests with a JSON body no longer time out. - `appendText` now correctly attributes the new text to the specified author. - `createDiffHTML` no longer fails with `Not a changeset: undefined`. - Added `padId` to the `padUpdate` / `padCreate` hook context. - Fixed `numConnectedUsers` to include the joining user in its count. - Accessibility improvements: keyboard trap fix, better screen reader support, and `aria-live` announcements. - RTL URL parameter `rtl=false` now correctly disables RTL mode. - Language dropdown is now sorted alphabetically by native name. - PageDown now advances the caret by a full page of lines. - ESM/CJS interop issues in the Settings module that had been breaking plugin compatibility have been resolved, with setters added to the CJS compatibility layer and regression tests in place. - Several Docker build fixes: git submodule handling, `hardlink` package-import-method for ZFS, and production-only workspace config. ### Other - Many occurrences of "etherpad-lite" have been renamed to "etherpad" across the codebase and documentation. - Pinned 33 transitive dependencies to patched versions to clear out Dependabot security alerts. - Restricted `GITHUB_TOKEN` permissions in the update-plugins workflow. # 2.6.1 For those wondering where the new updates are and why it was very quite throughout the last 1 1/2 years – I've been working on a new implementation of Etherpad from scratch in Go. It's called Etherpad-Go and you can find it here: `https://github.com/ether/etherpad-go` and a short FAQ about it here: https://github.com/ether/etherpad-go/wiki/FAQ . I'd love to hear your feedback about it either on Discord or issue tracker. There is a README.md that explains how to get started and try it out and also the FAQ can be quite fruitful. Latest release can be found here: https://github.com/ether/etherpad-go/releases/tag/v0.0.4 ### Notable enhancements and fixes of this release - Minor fixes and improvements to the session transfer feature introduced in 2.6.0 - Dependencies upgrades # 2.6.0 ### Notable enhancements and fixes - Added native option to transfer your Etherpad session between browsers. If you use multiple browsers or different PC for Etherpad they are different sessions. Meaning typing on one PC and then switching to another one in the same pad will result in different authorship colors. With this new feature you can now transfer your session to another browser or PC. To do so, open the home page and click on the wheel icon in the top right corner. After that click through the first dialog prompting you to copy a code to your clipboard. On your second browser open the same dialog and switch to "Receive Session" tab. There you can paste the code you copied before and click on "Receive Session". After that your session is transferred, and you can continue editing with the same authorship color as before. Just be aware that you can't have two active sessions at once in a pad. - Updated to oidc provider v2.6.0 after resolving compatibility issues. 🎉 For all the people celebrating: Have a happy and awesome new year! 🎉 There is something big on the horizon for Etherpad in 2026. Stay tuned! # 2.5.3 ### Notable enhancements and fixes - Fixed an issue with the release script that caused the release to not be created correctly. # 2.5.2 ### Notable enhancements and fixes - Fixes the no skin theme having an overlapping - Adds a new setting to disable recent pads to be shown. By setting `showRecentPads` to false in the `settings.json` file you can disable the recent pads feature on the home screen. - Sets the oidc-provider version to 9.5.1 as 9.5.2 crashes Etherpad on startup. # 2.5.1 ### Notable enhancements and fixes - Added endpoint for prometheus scraping. You can now scrape the metrics endpoint with prometheus. It is available at /stats/prometheus if you have enableMetrics set to true in your settings.json - fixed exposeVersion causing the pad panel to not load correctly - fixed admin manage pad url to also take the base path into account # 2.5.0 ### Notable enhancements and fixes - Updated to express 5.0.0. This is a major update to express that brings a lot of improvements and fixes. Please update all your plugins to the latest version to ensure compatibility. A lot changed in the route matching, and thus old plugins will throw errors and crash Etherpad. - Fixed an issue with the no-skin theme with cookie recentPadList feature - Fixed layout issues with the no-skin theme # 2.4.2 ### Notable enhancements and fixes - Fixed a german translation in the english translation file. # 2.4.1 ### Notable enhancements and fixes - Added generating release through ci cd pipeline. - Readded temporarily disabled workflows after release generation works again # 2.4.0 ### Notable enhancements and fixes - Added home button to the pad panel. To show it in your current instance, please copy the updated "toolbar" settings from the `settings.json.template` file to your `settings.json` file. - Added more current design for the default collibri theme. - Added handling of recent visited pads in the collibri theme. You can now access the most recent three pads you visited in the pad panel. - Disable stats endpoints if enableMetrics is set to false. This allows you to disable the metrics endpoints if you don't want to use them. - Use Node LTS instead of always latest Node version. # 2.3.2 ### Notable enhancements and fixes - Fixed admin ui displaying incorrect text # 2.3.1 ### Notable enhancements and fixes - Dependency updates # 2.3.0 ### Notable enhancements and fixes - Added possibility to cluster Etherpads behind reverse proxy. There is now a new reverse proxy designed for Etherpads that handles multiple Etherpads and the created pads in them. It will assign the pad assignement to an Etherpad at random but once the choice was made it will always reverse proxy the same backend. This allows to host multiple concurrent Etherpads and benefit from multi core systems even though one Etherpad is singlethreaded. - Added reverse proxy configuration for replacing Nginx. In the past there were some issues with nginx and its configuration. This reverse proxy allows you to handle your configuration with ease. If you want to find out more about the reverse proxy method check out the repository https://github.com/ether/etherpad-proxy . It also contains a sample docker-compose file with three Etherpads and one etherpad-proxy. Of course you need to adapt the settings.json.template to your liking and map it into the reverse proxy image before you are ready :). - Added client authorization to work with Etherpad. Before it would get blocked because it doesn't have the required claim. As this is now fixed etherpad-proxy can also work with your new OAuth2 configuration and retrieve a token via client credentials flow. # 2.2.7 ### Notable enhancements and fixes - We migrated all important pages to React 19 and React Router v7 Besides that only dependency updates. -> Have a merry Christmas and a happy new year. 🎄 🎁 # 2.2.6 ### Notable enhancements and fixes - Added option to delete a pad by the creator. This option can be found in the settings menu. When you click on it you get a confirm dialog and after that you have the chance to completely erase the pad. # 2.2.5 ### Notable enhancements and fixes - Fixed timeslider not scrolling when the revision count is a multiple of 100 - Added new Restful API for version 2 of Etherpad. It is available at /api-docs # 2.2.4 ### Notable enhancements and fixes - Switched to new SQLite backend - Fixed rusty-store-kv module not found # 2.2.3 ### Notable enhancements and fixes - Introduced a new in process database `rustydb` that represents a fast key value store written in Rust. - Readded window._ as a shortcut for getting text - Added support for migrating any ueberdb database to another. You can now switch as you please. See here: https://docs.etherpad.org/cli.html - Further Typescript movements - A lot of security issues fixed and reviewed in this release. Please update. # 2.2.2 ### Notable enhancements and fixes - Removal of Etherpad require kernel: We finally managed to include esbuild to bundle our frontend code together. So no matter how many plugins your server has it is always one JavaScript file. This boosts performance dramatically. - Added log layoutType: This lets you print the log in either colored or basic (black and white text) - Introduced esbuild for bundling CSS files - Cache all files to be bundled in memory for faster load speed # 2.1.1 ### Notable enhancements and fixes - Fixed failing Docker build when checked out as git submodule. Thanks to @neurolabs - Fixed: Fallback to websocket and polling when unknown(old) config is present for socket io - Fixed: Next page disabled if zero page by @samyakj023 - On CTRL+CLICK bring the window back to focus by Helder Sepulveda # 2.1.0 ### Notable enhancements and fixes - Added PWA support. You can now add your Etherpad instance to your home screen on your mobile device or desktop. - Fixed live plugin manager versions clashing. Thanks to @yacchin1205 - Fixed a bug in the pad panel where pagination was not working correctly when sorting by pad name ### Compatibility changes - Reintroduced APIKey.txt support. You can now switch between APIKey and OAuth2.0 authentication. This can be toggled with the setting authenticationMethod. The default is OAuth2. If you want to use the APIKey method you can set that to `apikey`. # 2.0.3 ### Notable enhancements and fixes - Added documentation for replacing apikeys with oauth2 - Bumped live plugin manager to 0.20.0. Thanks to @fgreinacher - Added better documentation for using docker-compose with Etherpad # 2.0.2 ### Notable enhancements and fixes - Fixed the locale loading in the admin panel - Added OAuth2.0 support for the Etherpad API. You can now log in into the Etherpad API with your admin user using OAuth2 ### Compatibility changes - The tests now require generating a token from the OAuth secret. You can find the `generateJWTToken` in the common.ts script for plugin endpoint updates. # 2.0.1 ### Notable enhancements and fixes - Fixed a bug where a plugin depending on a scoped dependency would not install successfully. # 2.0.0 ### Compatibility changes - Socket io has been updated to 4.7.5. This means that the json.send function won't work anymore and needs to be changed to .emit('message', myObj) - Deprecating npm version 6 in favor of pnpm: We have made the decision to switch to the well established pnpm (https://pnpm.io/). It works by symlinking dependencies into a global directory allowing you to have a cleaner and more reliable environment. - Introducing Typescript to the Etherpad core: Etherpad core logic has been rewritten in Typescript allowing for compiler checking of errors. - Rewritten Admin Panel: The Admin panel has been rewritten in React and now features a more pleasant user experience. It now also features an integrated pad searching with sorting functionality. ### Notable enhancements and fixes * Bugfixes - Live Plugin Manager: The live plugin manager caused problems when a plugin had depdendencies defined. This issue is now resolved. * Enhancements - pnpm Workspaces: In addition to pnpm we introduced workspaces. A clean way to manage multiple bounded contexts like the admin panel or the bin folder. - Bin folder: The bin folder has been moved from the src folder to the root folder. This change was necessary as the contained scripts do not represent core functionality of the user. - Starting Etherpad: Etherpad can now be started with a single command: `pnpm run prod` in the root directory. - Installing Etherpad: Etherpad no longer symlinks itself in the root directory. This is now also taken care by pnpm, and it just creates a node_modules folder with the src directory`s ep_etherpad-lite folder - Plugins can now be installed simply via the command: `pnpm run plugins i first-plugin second-plugin` or if you want to install from path you can do: `pnpm run plugins i --path ../path-to-plugin` # 1.9.7 ### Notable enhancements and fixes * Added Live Plugin Manager: Plugins are now installed into a separate folder on the host system. This folder is called `plugin_packages`. That way the plugins are separated from the normal etherpad installation. * Make repairPad.js more verbose * Fixed favicon not being loaded correctly # 1.9.6 ### Notable enhancements and fixes * Prevent etherpad crash when update server is not reachable * Use npm@6 in Docker build * Fix setting the log level in settings.json # 1.9.5 ### Compatibility changes * This version deprecates NodeJS16 as it reached its end of life and won't receive any updates. So to get started with Etherpad v1.9.5 you need NodeJS 18 and above. * The bundled windows NodeJS version has been bumped to the current LTS version 20. ### Notable enhancements and fixes * The support for the tidy program to tidy up HTML files has been removed. This decision was made because it hasn't been updated for years and also caused an incompability when exporting a pad with Abiword. # 1.9.4 ### Compatibility changes * Log4js has been updated to the latest version. As it involved a bump of 6 major version. A lot has changed since then. Most notably the console appender has been deprecated. You can find out more about it [here](https://github.com/log4js-node/log4js-node) ### Notable enhancements and fixes * Fix for MySQL: The logger calls were incorrectly configured leading to a crash when e.g. somebody uses a different encoding than standard MySQL encoding. # 1.9.3 ### Compability changes * express-rate-limit has been bumped to 7.0.0: This involves the breaking change that "max: 0" in the importExportRateLimiting is set to always trigger. So set it to your desired value. If you haven't changed that value in the settings.json you are all set. ### Notable enhancements and fixes * Bugfixes * Fix etherpad crashing with mongodb database * Enhancements * Add surrealdb database support. You can find out more about this database [here](https://surrealdb.com). * Make sqlite faster: The sqlite library has been switched to better-sqlite3. This should lead to better performance. # 1.9.2 ### Notable enhancements and fixes * Security * Enable session key rotation: This setting can be enabled in the settings.json. It changes the signing key for the cookie authentication in a fixed interval. * Bugfixes * Fix appendRevision when creating a new pad via the API without a text. * Enhancements * Bump JQuery to version 3.7 * Update elasticsearch connector to version 8 ### Compatibility changes * No compability changes as JQuery maintains excellent backwards compatibility. #### For plugin authors * Please update to JQuery 3.7. There is an excellent deprecation guide over [here](https://api.jquery.com/category/deprecated/). Version 3.1 to 3.7 are relevant for the upgrade. # 1.9.1 ### Notable enhancements and fixes * Security * Limit requested revisions in timeslider and export to head revision. (affects v1.9.0) * Bugfixes * revisions in `CHANGESET_REQ` (timeslider) and export (txt, html, custom) are now checked to be numbers. * bump sql for audit fix * Enhancements * Add keybinding meta-backspace to delete to beginning of line * Fix automatic Windows build via GitHub Actions * Enable docs to be build cross platform thanks to asciidoctor ### Compatibility changes * tests: drop windows 7 test coverage & use chrome latest for admin tests * Require Node 16 for Etherpad and target Node 20 for testing # 1.9.0 ### Notable enhancements and fixes * Windows build: * The bundled `node.exe` was upgraded from v12 to v16. * The bundled `node.exe` is now a 64-bit executable. If you need the 32-bit version you must download and install Node.js yourself. * Improvements to login session management: * `express_sid` cookies and `sessionstorage:*` database records are no longer created unless `requireAuthentication` is `true` (or a plugin causes them to be created). * Login sessions now have a finite lifetime by default (10 days after leaving). * `sessionstorage:*` database records are automatically deleted when the login session expires (with some exceptions that will be fixed in the future). * Requests for static content (e.g., `/robots.txt`) and special pages (e.g., the HTTP API, `/stats`) no longer create login session state. * The secret used to sign the `express_sid` cookie is now automatically regenerated every day (called *key rotation*) by default. If key rotation is enabled, the now-deprecated `SESSIONKEY.txt` file can be safely deleted after Etherpad starts up (its content is read and saved to the database and used to validate signatures from old cookies until they expire). * The following settings from `settings.json` are now applied as expected (they were unintentionally ignored before): * `padOptions.lang` * `padOptions.showChat` * `padOptions.userColor` * `padOptions.userName` * HTTP API: * Fixed the return value of `getText` when called with a specific revision. * Fixed a potential attribute pool corruption bug with `copyPadWithoutHistory`. * Mappings created by `createGroupIfNotExistsFor` are now removed from the database when the group is deleted. * Fixed race conditions in the `setText`, `appendText`, and `restoreRevision` functions. * Added an optional `authorId` parameter to `appendText`, `copyPadWithoutHistory`, `createGroupPad`, `createPad`, `restoreRevision`, `setHTML`, and `setText`, and bumped the latest API version to 1.3.0. * Fixed a crash if the database is busy enough to cause a query timeout. * New `/health` endpoint for getting information about Etherpad's health (see [draft-inadarei-api-health-check-06](https://www.ietf.org/archive/id/draft-inadarei-api-health-check-06.html)). * Docker now uses the new `/health` endpoint for health checks, which avoids issues when authentication is enabled. It also avoids the unnecessary creation of database records for managing browser sessions. * When copying a pad, the pad's records are copied in batches to avoid database timeouts with large pads. * Exporting a large pad to `.etherpad` format should be faster thanks to bulk database record fetches. * When importing an `.etherpad` file, records are now saved to the database in batches to avoid database timeouts with large pads. #### For plugin authors * New `expressPreSession` server-side hook. * Pad server-side hook changes: * `padCheck`: New hook. * `padCopy`: New `srcPad` and `dstPad` context properties. * `padDefaultContent`: New hook. * `padRemove`: New `pad` context property. * The `db` property on Pad objects is now public. * New `getAuthorId` server-side hook. * New APIs for processing attributes: `ep_etherpad-lite/static/js/attributes` (low-level API) and `ep_etherpad-lite/static/js/AttributeMap` (high-level API). * The `import` server-side hook has a new `ImportError` context property. * New `exportEtherpad` and `importEtherpad` server-side hooks. * The `handleMessageSecurity` and `handleMessage` server-side hooks have a new `sessionInfo` context property that includes the user's author ID, the pad ID, and whether the user only has read-only access. * The `handleMessageSecurity` server-side hook can now be used to grant write access for the current message only. * The `init_` server-side hooks have a new `logger` context property that plugins can use to log messages. * Prevent infinite loop when exiting the server * Bump dependencies ### Compatibility changes * Node.js v14.15.0 or later is now required. * The default login session expiration (applicable if `requireAuthentication` is `true`) changed from never to 10 days after the user leaves. #### For plugin authors * The `client` context property for the `handleMessageSecurity` and `handleMessage` server-side hooks is deprecated; use the `socket` context property instead. * Pad server-side hook changes: * `padCopy`: * The `originalPad` context property is deprecated; use `srcPad` instead. * The `destinationID` context property is deprecated; use `dstPad.id` instead. * `padCreate`: The `author` context property is deprecated; use the new `authorId` context property instead. Also, the hook now runs asynchronously. * `padLoad`: Now runs when a temporary Pad object is created during import. Also, it now runs asynchronously. * `padRemove`: The `padID` context property is deprecated; use `pad.id` instead. * `padUpdate`: The `author` context property is deprecated; use the new `authorId` context property instead. Also, the hook now runs asynchronously. * Returning `true` from a `handleMessageSecurity` hook function is deprecated; return `'permitOnce'` instead. * Changes to the `src/static/js/Changeset.js` library: * The following attribute processing functions are deprecated (use the new attribute APIs instead): * `attribsAttributeValue()` * `eachAttribNumber()` * `makeAttribsString()` * `opAttributeValue()` * `opIterator()`: Deprecated in favor of the new `deserializeOps()` generator function. * `appendATextToAssembler()`: Deprecated in favor of the new `opsFromAText()` generator function. * `newOp()`: Deprecated in favor of the new `Op` class. * The `AuthorManager.getAuthor4Token()` function is deprecated; use the new `AuthorManager.getAuthorId()` function instead. * The exported database records covered by the `exportEtherpadAdditionalContent` server-side hook now include keys like `${customPrefix}:${padId}:*`, not just `${customPrefix}:${padId}`. * Plugin locales should overwrite core's locales Stale * Plugin locales overwrite core locales # 1.8.18 Released: 2022-05-05 ### Notable enhancements and fixes * Upgraded ueberDB to fix a regression with CouchDB. # 1.8.17 Released: 2022-02-23 ### Security fixes * Fixed a vunlerability in the `CHANGESET_REQ` message handler that allowed a user with any access to read any pad if the pad ID is known. ### Notable enhancements and fixes * Fixed a bug that caused all pad edit messages received at the server to go through a single queue. Now there is a separate queue per pad as intended, which should reduce message processing latency when many pads are active at the same time. # 1.8.16 ### Security fixes If you cannot upgrade to v1.8.16 for some reason, you are encouraged to try cherry-picking the fixes to the version you are running: ```shell git cherry-pick b7065eb9a0ec..77bcb507b30e ``` * Maliciously crafted `.etherpad` files can no longer overwrite arbitrary non-pad database records when imported. * Imported `.etherpad` files are now subject to numerous consistency checks before any records are written to the database. This should help avoid denial-of-service attacks via imports of malformed `.etherpad` files. ### Notable enhancements and fixes * Fixed several `.etherpad` import bugs. * Improved support for large `.etherpad` imports. # 1.8.15 ### Security fixes * Fixed leak of the writable pad ID when exporting from the pad's read-only ID. This only matters if you treat the writeable pad IDs as secret (e.g., you are not using [ep_padlist2](https://www.npmjs.com/package/ep_padlist2)) and you share the pad's read-only ID with untrusted users. Instead of treating writeable pad IDs as secret, you are encouraged to take advantage of Etherpad's authentication and authorization mechanisms (e.g., use [ep_openid_connect](https://www.npmjs.com/package/ep_openid_connect) with [ep_readonly_guest](https://www.npmjs.com/package/ep_readonly_guest), or write your own [authentication](https://etherpad.org/doc/v1.8.14/#index_authenticate) and [authorization](https://etherpad.org/doc/v1.8.14/#index_authorize) plugins). * Updated dependencies. ### Compatibility changes * The `logconfig` setting is deprecated. #### For plugin authors * Etherpad now uses [jsdom](https://github.com/jsdom/jsdom) instead of [cheerio](https://cheerio.js.org/) for processing HTML imports. There are two consequences of this change: * `require('ep_etherpad-lite/node_modules/cheerio')` no longer works. To fix, your plugin should directly depend on `cheerio` and do `require('cheerio')`. * The `collectContentImage` hook's `node` context property is now an [`HTMLImageElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement) object rather than a Cheerio Node-like object, so the API is slightly different. See [citizenos/ep_image_upload#49](https://github.com/citizenos/ep_image_upload/pull/49) for an example fix. * The `clientReady` server-side hook is deprecated; use the new `userJoin` hook instead. * The `init_` server-side hooks are now run every time Etherpad starts up, not just the first time after the named plugin is installed. * The `userLeave` server-side hook's context properties have changed: * `auth`: Deprecated. * `author`: Deprecated; use the new `authorId` property instead. * `readonly`: Deprecated; use the new `readOnly` property instead. * `rev`: Deprecated. * Changes to the `src/static/js/Changeset.js` library: * `opIterator()`: The unused start index parameter has been removed, as has the unused `lastIndex()` method on the returned object. * `smartOpAssembler()`: The returned object's `appendOpWithText()` method is deprecated without a replacement available to plugins (if you need one, let us know and we can make the private `opsFromText()` function public). * Several functions that should have never been public are no longer exported: `applyZip()`, `assert()`, `clearOp()`, `cloneOp()`, `copyOp()`, `error()`, `followAttributes()`, `opString()`, `stringOp()`, `textLinesMutator()`, `toBaseTen()`, `toSplices()`. ### Notable enhancements and fixes * Accessibility fix for JAWS screen readers. * Fixed "clear authorship" error (see issue #5128). * Etherpad now considers square brackets to be valid URL characters. * The server no longer crashes if an exception is thrown while processing a message from a client. * The `useMonospaceFontGlobal` setting now works (thanks @Lastpixl!). * Chat improvements: * The message input field is now a text area, allowing multi-line messages (use shift-enter to insert a newline). * Whitespace in chat messages is now preserved. * Docker improvements: * New `HEALTHCHECK` instruction (thanks @Gared!). * New `settings.json` variables: `DB_COLLECTION`, `DB_URL`, `SOCKETIO_MAX_HTTP_BUFFER_SIZE`, `DUMP_ON_UNCLEAN_EXIT` (thanks @JustAnotherArchivist!). * `.ep_initialized` files are no longer created. * Worked around a [Firefox Content Security Policy bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1721296) that caused CSP failures when `'self'` was in the CSP header. See issue #4975 for details. * UeberDB upgraded from v1.4.10 to v1.4.18. For details, see the [ueberDB changelog](https://github.com/ether/ueberDB/blob/master/CHANGELOG.md). Highlights: * The `postgrespool` driver was renamed to `postgres`, replacing the old driver of that name. If you used the old `postgres` driver, you may see an increase in the number of database connections. * For `postgres`, you can now set the `dbSettings` value in `settings.json` to a connection string (e.g., `"postgres://user:password@host/dbname"`) instead of an object. * For `mongodb`, the `dbName` setting was renamed to `database` (but `dbName` still works for backwards compatibility) and is now optional (if unset, the database name in `url` is used). * `/admin/settings` now honors the `--settings` command-line argument. * Fixed "Author *X* tried to submit changes as author *Y*" detection. * Error message display improvements. * Simplified pad reload after importing an `.etherpad` file. #### For plugin authors * `clientVars` was added to the context for the `postAceInit` client-side hook. Plugins should use this instead of the `clientVars` global variable. * New `userJoin` server-side hook. * The `userLeave` server-side hook has a new `socket` context property. * The `helper.aNewPad()` function (accessible to client-side tests) now accepts hook functions to inject when opening a pad. This can be used to test any new client-side hooks your plugin provides. * Chat improvements: * The `chatNewMessage` client-side hook context has new properties: * `message`: Provides access to the raw message object so that plugins can see the original unprocessed message text and any added metadata. * `rendered`: Allows plugins to completely override how the message is rendered in the UI. * New `chatSendMessage` client-side hook that enables plugins to process the text before sending it to the server or augment the message object with custom metadata. * New `chatNewMessage` server-side hook to process new chat messages before they are saved to the database and relayed to users. * Readability improvements to browser-side error stack traces. * Added support for socket.io message acknowledgments. # 1.8.14 ### Security fixes * Fixed a persistent XSS vulnerability in the Chat component. In case you can't update to 1.8.14 directly, we strongly recommend to cherry-pick a7968115581e20ef47a533e030f59f830486bdfa. Thanks to sonarsource for the professional disclosure. ### Compatibility changes * Node.js v12.13.0 or later is now required. * The `favicon` setting is now interpreted as a pathname to a favicon file, not a URL. Please see the documentation comment in `settings.json.template`. * The undocumented `faviconPad` and `faviconTimeslider` settings have been removed. * MySQL/MariaDB now uses connection pooling, which means you will see up to 10 connections to the MySQL/MariaDB server (by default) instead of 1. This might cause Etherpad to crash with a "ER_CON_COUNT_ERROR: Too many connections" error if your server is configured with a low connection limit. * Changes to environment variable substitution in `settings.json` (see the documentation comments in `settings.json.template` for details): * An environment variable set to the string "null" now becomes `null` instead of the string "null". Similarly, if the environment variable is unset and the default value is "null" (e.g., `"${UNSET_VAR:null}"`), the value now becomes `null` instead of the string "null". It is no longer possible to produce the string "null" via environment variable substitution. * An environment variable set to the string "undefined" now causes the setting to be removed instead of set to the string "undefined". Similarly, if the environment variable is unset and the default value is "undefined" (e.g., `"${UNSET_VAR:undefined}"`), the setting is now removed instead of set to the string "undefined". It is no longer possible to produce the string "undefined" via environment variable substitution. * Support for unset variables without a default value is now deprecated. Please change all instances of `"${FOO}"` in your `settings.json` to `${FOO:null}` to keep the current behavior. * The `DB_*` variable substitutions in `settings.json.docker` that previously defaulted to `null` now default to "undefined". * Calling `next` without argument when using `Changeset.opIterator` does always return a new Op. See b9753dcc7156d8471a5aa5b6c9b85af47f630aa8 for details. ### Notable enhancements and fixes * MySQL/MariaDB now uses connection pooling, which should improve stability and reduce latency. * Bulk database writes are now retried individually on write failure. * Minify: Avoid crash due to unhandled Promise rejection if stat fails. * padIds are now included in /socket.io query string, e.g. `https://video.etherpad.com/socket.io/?padId=AWESOME&EIO=3&transport=websocket&t=...&sid=...`. This is useful for directing pads to separate socket.io nodes. *