Repository navigation
Releases: ether/etherpad-integration-for-nextcloud
Release list
1.1.0-beta.2
Second beta release for 1.1.0. Pads keep their history while their files are in the trash, and missing pads can be recovered from the content saved in their files. This release also makes external pads and public links safer, revokes Etherpad sessions more reliably, and fixes a great many smaller bugs.
Highlights
- The trash keeps a pad. A
.padfile in the trash keeps its pad and its history, and a restore gives the same pad back. Moving a file to the trash, through WebDAV too, no longer loses what was written since its last sync. The pad is deleted once the file is deleted for good - from the trash, past it, with a folder, or with the account - by a background job within minutes, unless an administrator switched that off.docs/deleting-pads.mdsays what each way of deleting a file does. - Recover missing pads. If Etherpad has lost a pad, opening its file says so instead of showing an empty pad, and users who may edit the file can recreate the pad from the content saved in it. Restoring a file from the trash recreates a missing pad automatically.
- Pads of vanished files. Files removed outside Nextcloud leave their pads behind. The admin page lists them, and an administrator can delete them, one or all, or forget a public one.
- Safer external pads and public links. External pad addresses are checked the same way on every PHP version, and the connection stays pinned to the checked address, through a proxy too. Public links are rate-limited and reuse their Etherpad sessions. A writable link to a protected pad makes each visitor an Etherpad author of their own, up to 250 per link and hour where a memory cache is available.
- Sessions end with access. Deleting a protected pad's file revokes all of its Etherpad sessions, in the background where Etherpad is slow, and a deleted account loses its sessions as on a logout.
- Group restrictions apply to pad creation. Where the app is enabled for some groups only, users outside them can no longer create pads through the "New" menu, direct requests or a restore from the trash.
Upgrade
This version supports Nextcloud 32.0.9 to 34 and PHP 8.1 to 8.5. On Nextcloud 33, use 33.0.3 or later: the Viewer of 33.0.0 to 33.0.2 lacks a fix, and a click on a .pad file downloads it instead of opening the pad. Nextcloud 35 is not yet supported. If you use an older Nextcloud version, upgrade Nextcloud first while keeping your current app version. Then upgrade the app.
- Recommended: Back up your Nextcloud database.
- Replace the installed
etherpad_nextcloudfolder with the one from the release archive. - Run
php occ upgrade, or start the update offered by Nextcloud in the browser.
The update runs the app's database migration. It updates the existing pad bindings for the new trash behaviour, which keeps a pad while its file is in the trash, and carries the setting delete_on_trash over as delete_pad_with_file (see below). It also adds an index and removes the three obsolete background jobs and the test_fault setting.
Changes
- The setting
delete_on_trashis nowdelete_pad_with_fileand decides whether a file deleted for good takes its pad along. The upgrade takes over its value. - With
delete_pad_with_fileon, its default, a background job deletes the pads of files deleted for good. With a five-minute system cron that is usually five to ten minutes after the file was deleted for good; with AJAX or webcron it depends on how often those run. "Check pending pads" on the admin page starts a run at once. - Files already in the trash when you upgrade: with
delete_on_trashon, its default, 1.1.0-beta.1 deleted a file's pad when the file went to the trash. Restoring such a file creates a new pad from its saved snapshot, which brings back the saved content but not the pad's history. Where 1.1.0-beta.1 kept the pad, or could not delete it because Etherpad did not answer, restoring the file reuses it. - Pads 1.1.0-beta.1 left behind when their files were deleted for good - with
delete_on_trashoff, past the trash, inside a folder, after a rename, or with their account - show after the upgrade as pads of vanished files on the admin page, where they can be deleted. - If you saved the admin settings while external pads were switched off, check the external pad allowlist: that save emptied it, and an empty list admits every public HTTPS host.
- Scripts against the admin API:
retry-pending-deletesis nowsettle-pending; the connection test no longer answerspad_count, and a failed test answers 200 withok: false; the consistency check answersvanished_file_countinstead ofbinding_without_file_countandsamples.bindings_without_file.POST /api/v1/pads/trash,POST /api/v1/pads/restoreand the debug endpointPOST /api/v1/admin/test-faultare removed. - Other API callers: a file id has to be a positive integer, so ids such as
1e3or7.5are refused, andPOST /api/v1/pads/sync/{fileId}answers 403 to a user who may not change the file, where a reader got 200unchangedor a 500. - Pages that embed the create page:
epnc:create-failedwithreason: 'network'now means that no answer came and the outcome is unknown, and the event carries the server'scodeandretryable. - On Nextcloud 34, the pads of the files in a folder deleted for good, and in a trash emptied as a whole, stay until a Nextcloud 34 release has the fix Nextcloud 35.0.1 has; the consistency check lists them, and an administrator can delete them there. A public one stays reachable by its link until then.
- Public links count their visitors and keep their Etherpad sessions in Nextcloud's memory cache. With a local cache alone that holds for each web server on its own; without any, every open makes a session and all visitors share one author, as before.
Further changes
- The closing sync starts at once, even while another sync of the file runs. With Nextcloud's file locking on, syncs of the same file run one at a time, so two tabs no longer write an older revision over a newer one.
- Error messages are translated and explain possible next steps. The Viewer and the embed page offer "Try again" for temporary failures.
- Opening a protected pad keeps the cookies Nextcloud sets in the same answer, so a public link's first visit gets its Nextcloud session.
- Several admin settings fixes: the connection test before the first save, a trusted embed origin with
:443, and the detected Etherpad API version. - Credentials and pad text stay out of the exception traces Nextcloud writes to its log.
- DOMPurify updated to 3.4.17.
- The lifecycle cases of the trash and of team folders run against a real Nextcloud and Etherpad, the folder cases not on Nextcloud 34 before the fix above. Mutation testing covers the PHP lines a pull request changes, and each release is upgraded from the last one on every supported major.
1.1.0-beta.1
First beta release for 1.1.0. This release moves the integration closer to Nextcloud's native APIs, adds optional full-text indexing of pad content and tightens installation, migration and lifecycle behaviour.
Highlights
- Search inside pads. With Nextcloud's Full Text Search apps and a configured backend,
.padfiles can now be found by their stored plain-text content. Frontmatter, pad ids and snapshot HTML are not indexed, and per-storage indexing settings are respected. - Native Nextcloud Viewer integration. The Viewer is registered through the supported
@nextcloud/viewerAPI, while public shares use Nextcloud's own opening and file-action flows instead of custom route and DOM handling. - Reliable first installation. The
.padextension, MIME part andEtherpaddisplay name are registered when the app is installed. The icon stays inside the app rather than modifying Nextcloud's signed core files. - Safer legacy imports. Importing protected Ownpad group pads is disabled by default and can be enabled explicitly by an administrator where the Etherpad server is not shared with another group-pad creator.
Further changes
- Protected-pad sessions now last six hours for authenticated users and three hours through public shares.
- External pad snapshots preserve text containing the snapshot marker lines and no longer create repeated file versions for an unchanged pad.
- Cleanup after partially failed creation, initialisation, template materialisation and restoration is more consistent and concurrency-safe.
- The minimum supported Nextcloud version is now 31.0.9; Nextcloud 32, 33 and 34 remain supported.
- DOMPurify updated to 3.4.15.
- CI coverage now includes the exact supported Nextcloud floor, PHP 8.1 through 8.5 and a full Nextcloud 34 + Elasticsearch indexing stack.
Existing pads on an already configured Full Text Search installation can be indexed immediately with:
php occ fulltextsearch:index '{"provider":"files","force":true}'
1.1.0-alpha.5
This release focuses on correct read-only access, live read-only pad content, session lifecycle management, Nextcloud 34 support, and further hardening of the creation and public-share flows.
New features
- Live read-only pad viewer. Read-only users now see the current content from Etherpad instead of the last snapshot stored in the
.padfile. The view can be refreshed without reopening the file and supports safe links. - Nextcloud 34 support. The declared and tested compatibility range is now Nextcloud 31 through 34.
- Etherpad session cleanup. Expired sessions are collected in the background, and logging out of Nextcloud now revokes the user's active Etherpad sessions.
Access control and security
- Correct view-only sharing. Until now a share without write permission still opened a protected pad in the editor, because read-only handling existed only for public links. A "can view" recipient was issued an ordinary Etherpad session and could edit the pad everyone else opens. A protected pad now renders without a session; a public one gets Etherpad's read-only URL, which is presentation rather than enforcement, since a public pad is reachable by anyone holding its id. Writable shares are unaffected.
- Safer public-share resolution. Public shares now address pads primarily by their stable file ID. Renaming or moving a shared file therefore no longer breaks it, and ambiguous names such as
A+B.padandA B.padcannot resolve to the wrong file. - Hardened content retrieval. Live content responses are not cached, and permissions and bindings are checked for every request rather than only when the pad is opened. Fetching an external pad's export is capped at 5 MiB and follows no redirects, alongside the existing SSRF protections.
- Stricter frontmatter parsing. Pad metadata containing unsafe line breaks or NUL bytes is now rejected instead of being silently changed or interpreted as additional keys.
- Updated HTML sanitizer. DOMPurify was updated to 3.4.14 and the browser bundles were rebuilt.
- More compatible Content Security Policy. The obsolete
child-srcoverride was removed. It could interfere with Nextcloud workers and was incompatible with Nextcloud 34.
Reliability
- Race-safe file creation. Creation, initialization and rollback now operate on the identity and expected content of a file instead of trusting a potentially stale path or node object. Concurrent moves, replacements and duplicate requests can no longer cause the wrong file to be overwritten or deleted.
- Unified pad provisioning. New pads, restored pads and pads initialized from existing files now use the same provisioning and cleanup path. An access mode that path does not recognise is refused rather than turned into an unprotected pad.
- Unified frontend opening flow. The Viewer and embedded views now share one implementation for loading pad metadata, handling read-only content and normalizing synchronization intervals. The embedded view had been accepting any interval the server sent; the bound it gets now is the one a browser timer can actually hold.
- Public shares fall back again on unhandled file types. Clicking a shared file whose type the Viewer does not handle had nothing left to fall back to, because every asynchronous rejection from the Viewer was being swallowed. Only expected navigation redirects are ignored now.
- Machine-readable API errors. The frontend now reacts to stable error codes such as
missing_frontmatterinstead of matching translated English messages. - Single-pass pad parsing. A
.padfile is parsed once and passed through the opening and initialization flow as structured data.
File handling
- MIME-part repair. Existing
.padfiles receive the correct MIME part during upgrades, improving compatibility with MIME-based filters and search integrations. A folder namedArchive.padis no longer rewritten as a pad file. - Consistent
.padrecognition. Filename, extension and MIME rules are centralized. Uppercase.PADfiles, including files opened through DAV links, are now handled consistently. - Obsolete Files API integration removed. The old
window.OCA.Files.fileActionsregistration, which is unavailable on every supported Nextcloud version, has been removed. The native Nextcloud Viewer integration remains responsible for opening pads.
Testing and maintenance
- Added end-to-end coverage for read-only access, live content, public shares, session cleanup and logout revocation.
- Extended the CI and end-to-end matrices to cover Nextcloud 34, and added a check that holds seven files – the Psalm and end-to-end matrices, three stack defaults,
composer.jsonand the README – to the compatibility range declared inappinfo/info.xml. - Centralized duplicated file-type, Viewer URL, creation and opening rules.
- Time-dependent services now read the clock through Nextcloud's
ITimeFactory, which removes the last source of timestamp flakiness from the tests. - Updated development requirements to Node.js
^24.15.0and npm^11.0.0. - Updated the development-only
fast-uri,browserslistandhappy-domdependencies.
Upgrading
No manual migration steps are required.
The post-migration repair updates the MIME metadata of existing .pad files automatically.
If you shared a protected pad read-only on an earlier version, those recipients could edit it until now. Such a share opens the live read-only view from this release on.
The supported Nextcloud range is 31 through 34.
1.1.0-alpha.4
This release focuses on a simpler pad creation flow, shared templates, clearer administration, more reliable protected-pad handling, and broader automated compatibility testing.
New features
- Instance-wide pad templates: Administrators can upload and manage shared
.padtemplates. They appear in Nextcloud's template picker for all users and always create a fresh Etherpad pad. - Unified pad creation: The separate entries for protected, public, and external pads in Nextcloud's New menu have been replaced by a single New pad entry. The pad type and shared templates are now selected through Nextcloud's native template picker.
- Configurable pad types: Administrators can independently enable or disable protected and public pads. Existing pads remain usable even when their type is disabled. External pads continue to use their own setting.
- Italian translations: Italian joins German, Spanish, and French as a maintained translation.
Admin settings and diagnostics
- Reorganised the administration page into clearer sections and revised the descriptions to make configuration easier to understand.
- Improved the Etherpad connection test with separate results for the API, API key, browser-facing Etherpad URL, and protected-pad session-cookie setup.
- Unified the session-cookie-domain calculation used by the settings page, diagnostics, and runtime.
- Added clearer, field-specific guidance when a setting needs attention.
Reliability and security
- Session cookie changes. The Etherpad session cookie is now
SameSite=Laxinstead ofNone, so a foreign page that frames a pad URL no longer receives it. From Etherpad 3.0 the cookie is alsoHttpOnly; up to 2.7.3 the pad app reads it in the browser, where that would prevent protected pads from opening. The release is detected from Etherpad's/healthendpoint. Two app settings exist for deployments that need to override either:etherpad_session_cookie_samesiteandetherpad_http_only_session_cookie. - Multiple protected pads can now remain open in different browser tabs without replacing each other's Etherpad session.
- Deleting a protected pad now removes its complete Etherpad group and associated sessions instead of leaving group resources behind.
- Strengthened cleanup and rollback handling when pad creation, binding, restoration, or deletion only partially succeeds.
- Pad opening by file ID is now more reliable for group folders, shares, external storage, and files whose path has changed.
- Hardened legacy Ownpad migration against forged group-pad identifiers.
- Improved concurrent file creation and filename handling, including names containing special characters.
- Fixed restoring
.padfiles from the trash on Nextcloud 31. - Added numerous smaller error-handling and compatibility fixes across pad creation, opening, templates, snapshots, and lifecycle operations.
Testing and maintenance
- Added a disposable Docker-based end-to-end test environment containing Nextcloud, Etherpad, PostgreSQL, and TLS.
- The Playwright suite now runs automatically against Nextcloud 31, 32, and 33 as well as Etherpad 2 and 3.
- Expanded browser and unit coverage for pad creation, templates, shares, protected sessions, trash and restore, lifecycle cleanup, and security-sensitive flows.
- Improved test cleanup so automated runs do not leave files in the Nextcloud trash.
- Updated DOMPurify and rebuilt the distributed frontend bundles with the patched version.
- Cleaned the release archive and excluded development-only Playwright artifacts.
Upgrading
No manual steps. Existing pads, bindings and settings are carried over.
Administrators running a cross-site embed of the /embed/by-id routes should read the SameSite section in docs/etherpad-integration.md before upgrading: the cookie is same-site by default now, and a cross-site embed needs etherpad_session_cookie_samesite=none together with authentication that does not travel in a cookie.
v1.1.0-alpha.3
Third public-review release. Builds on v1.1.0-alpha.2 with security hardening, a browser end-to-end test suite, and a deep static-analysis / tech-debt pass. No user-facing feature changes since alpha.2.
- Security hardening
- Etherpad API key stored as sensitive app config (masked in
occ/diagnostics instead of clear text). - External-pad framing now requires an explicit trusted-origin allowlist (no implicit CSP
frame-src). - Snapshot HTML sanitised client-side with DOMPurify before rendering.
- Etherpad API key stored as sensitive app config (masked in
- Internal changes — Etherpad HTTP via Nextcloud's
IClientService; shared pad-sync frontend module; MIME registration removed from the per-requestApplicationconstructor; legacyRetryPendingDeleteJobshim retired in favour of the tiered Hot/Warm/Cold jobs; dead-code removal. - Tests & tooling — Playwright end-to-end suite (23 browser tests against live Nextcloud + Etherpad); Psalm static analysis enabled in CI with the baseline burned down to zero real type issues plus
findUnusedCode; CI guards for stalejs/assets and version metadata consistency.
See CHANGELOG.md for the complete list of changes.
Not for production yet. This is a pre-release for testing and review.
v1.1.0-alpha.2
Second public-review release. Builds on v1.1.0-alpha.1 with cleaner translations, embed-create host signalling, and proper CI.
-
Localisation rework — DE/ES/FR catalogs cleaned up and consistent (132/132 each, no orphans, alphabetically sorted). Renamed several English source strings for clarity (
Test Etherpad connectioninstead ofHealth check,.pad file …instead ofPad file …, etc.).de_DEmirror and legacy*.phpcatalogs dropped — only*.json+*.jsper locale now.Translation quality: DE has been reviewed end-to-end by a native speaker. ES and FR are first-pass translations (AI + school grammar) — usable baseline, but expected to get native-speaker polish via translatewiki once the project is onboarded.
-
Embed-create result events —
/embed/create-by-parentnow postMessagesepnc:create-succeeded/epnc:create-failedto its parent host so embedders can react to create outcomes. -
CI in place — PHPUnit on PHP 8.2/8.3/8.4, npm-build + vitest, info.xml schema lint. Dependabot configured for npm / composer / actions.
-
Release tarball builder
scripts/build-release-tarball.sh. -
App icon for the Apps page in NC settings (
img/etherpad_nextcloud.svg).
See CHANGELOG.md for the complete list of changes.
Not for production yet. This is a pre-release for testing and review.
v1.1.0-alpha.1 — first reviewer-facing alpha
First reviewer-facing cut after the March 1.0.0 tag. Not for production yet — install on dev/staging only.
How to install
- Download
etherpad_nextcloud-1.1.0-alpha.1.tar.gz(asset below). - Extract into
<nextcloud-root>/apps/so the path is<nextcloud-root>/apps/etherpad_nextcloud/. php occ app:enable etherpad_nextcloud- If
.padicons or actions don't show up:php occ maintenance:mimetype:update-js && php occ maintenance:mimetype:update-db - Open admin settings → Etherpad integration → set host + API key.
What's worth testing
- Create:
+ → New pad(with and without templates), edit, close. Check the file syncs back. - Open: existing
.padfiles; protected and public access modes. - Templates: drop a
.padin/Templates, pick it from+ → New pad. Try the{{date}}/{{user}}placeholders. - Public share: share a
.padvia public link, open in an incognito tab. - Trash / restore: trash a
.pad, restore from NC's "Deleted files". - Legacy Ownpad migration: drop an
[InternetShortcut].padinto your files, open it — should silently migrate. (Seedocs/legacy-ownpad-migration.md.) - Embed integration: if you embed NC content from another origin, try
/embed/by-id/{fileId}after configuringtrusted_embed_origins.
Known cosmetic issues
- Two transient errors in the browser console on the very first
+ → New padper session (one/core/preview400 withfileId=-1, one Tiptap unmount warning). Both originate from NC's Files-app placeholder-rendering phase, not from this app. Tracked as a follow-up (#72).
Reporting issues
Please file a GitHub issue with:
- NC version + PHP version + Etherpad version
- What action triggered the issue
- Browser console output (if frontend) or
nextcloud.loglines (if backend)
What's in 1.1.0-alpha.1
See the CHANGELOG entry for the full list. Highlights since 1.0.0:
- Pad templates with placeholder substitution
- Legacy Ownpad lazy auto-migration
- Trusted embed integration
- External integration APIs (
from-template,from-url,create-by-parent,meta-by-id) - Architecture cleanup (split
PadController, extractedExternalPadExportFetcher, etc.) - Faster protected-pad open + closer-flush ack protocol