Third public-review release. Focus: security hardening of the Etherpad/admin surface, a browser end-to-end test suite, and a deep static-analysis / tech-debt pass. No user-facing feature changes since alpha.2.
- API key stored as sensitive app config. The Etherpad API key is now persisted via the sensitive-value app-config path so it is masked in
occ configoutput and admin diagnostics instead of being readable in clear text. (#105) - External-pad framing requires an explicit allowlist. The CSP
frame-srcfor external Etherpad hosts is no longer opened implicitly; embedding an external pad now requires the host to be on the trusted-origin allowlist. (#102) - Client-side snapshot sanitisation. Snapshot HTML is sanitised with DOMPurify in the browser before rendering, closing a stored-HTML surface in the viewer/recovery path. (#110)
- Etherpad HTTP via
IClientService. Outbound Etherpad API calls go through Nextcloud's HTTP client instead of raw transport, picking up proxy/TLS configuration and consistent timeouts. (#103) - Shared pad-sync frontend module. The viewer and embed entry points now share one extracted pad-sync module instead of duplicating the loop. (#106)
- No per-request MIME registration. Dropped the MIME-type registration from the
Applicationconstructor (it ran on every request); the.padMIME type is owned solely by theRegisterMimeTyperepair step. (#108) - Legacy retry job retired. Removed the compatibility
RetryPendingDeleteJobshim; the tiered Hot/Warm/ColdTimedJobs are the sole retry path for pending pad deletes. (#111) - Removed a batch of dead code surfaced during the refactors. (#104)
- Playwright end-to-end suite. 23 browser tests against a live Nextcloud + Etherpad covering create/open, templates + placeholders, trash/restore, move/rename, orphan recovery, ownership boundary, snapshot round-trip, user-to-user share, public-share view, and the admin health check. (#54)
- Psalm static analysis enabled in CI with a baseline (#82), then the baseline was burned down: noise reduction via config + stubs + redundant-cast removal (#122/#133), all real type issues fixed so the type baseline is empty, and
findUnusedCodeturned on with@psalm-api-annotated entry points (#122/#134). - CI now fails the build when committed
js/assets are stale. (#101) - Version metadata aligned across
appinfo/info.xml,package.json, andpackage-lock.json, guarded by a version-consistency CI check. (#107, #119)
Second public-review release. Focus: localisation cleanup, embed-create host signalling, and CI / release infrastructure.
- Embed-create result events. The
/embed/create-by-parentflow now emitsepnc:create-succeeded/epnc:create-failedpostMessages to the parent host so embedders can react to the create outcome without scraping the iframe. (#95, #96) - GitHub Actions CI (
lint-info-xml, PHPUnit on PHP 8.2/8.3/8.4, npm-build + vitest, info.xml schema check), Dependabot config for npm, composer, and actions. (#75, #83) - Release tarball builder
scripts/build-release-tarball.shfor reproducible app-store-style builds. (#74) - NC-discoverable app icon at
img/etherpad_nextcloud.svg(+ dark variant + 512 px PNG) so the Apps page in NC settings shows the Etherpad icon instead of the generic placeholder. (#84)
- Locale cleanup for 1.1.0. All maintained locales (
de,es,fr) brought to 132/132 keys with no orphans. Source strings consolidated (Health check→Test Etherpad connection,Pad file→.pad file, unifiedCould not …/Unable to …pairs,External Etherpad host allowlist, …). DE locale reviewed end-to-end by a native speaker (Du-form, full terminology pass). ES and FR are best-effort first-pass translations done with AI assistance + school-level grammar — usable but expected to receive native-speaker polish via translatewiki once the project is onboarded (#98). Dropped thede_DEmirror and the legacy*.phpcatalogs — only*.json+*.jsper locale, alphabetically sorted for clean cross-locale diffs.docs/i18n.mdrewritten for the new layout. (#77) appinfo/info.xmlschema now validates against the official apps.nextcloud.com schema; John McLear added as second author for the Etherpad upstream. (#94)- Dev dependencies refreshed via Dependabot (actions/setup-node 6, actions/checkout 6, actions/cache 5, shivammathur/setup-php 2.37, vitest 4.1.7, dorny/paths-filter 4, skjnldsv/read-package-engines-version-actions 3).
fileId=-1preview 400 on fresh-pad create (#99) — reproduced with plain+ → New Markdown file; root cause is hard-coded in NC core'sPreviewControllerand not actionable plugin-side. Closed as upstream.- Tiptap unmount warning on fresh-pad create (#72) — re-diagnosed as NC Text-app
RichWorkspacemounting on page load (fires regardless of pad create). Not in our flow. Closed as wrong diagnosis.
First public-review release. Versioning reset to a clean minor cut with a pre-release marker; not intended for production deployments yet.
- Pad templates. Users can place
.padfiles in their/Templatesfolder and pick them from the+ → New padmenu. Mustache-style placeholder substitution for{{date}},{{user}}, etc., with same-server access-mode inheritance and a claim-collision guard. Seedocs/templates.md. - Legacy Ownpad migration.
.padfiles in the old[InternetShortcut]format are auto-converted on first open. Branching depends on the source URL's origin (same- vs. cross-server) and the pad-id format (g.X$Y→ protected, anything else → public); claim-collision rule prevents one user's legacy file from claiming another user's bound pad. Seedocs/legacy-ownpad-migration.md. - Trusted embed integration for same-site / trusted-origin hosts:
- minimal authenticated embed page via
/embed/by-id/{fileId} - trusted
frame-ancestors/ embed-origin allowlist - same-origin open flow with CSRF bootstrap inside blank template
- minimal authenticated embed page via
- Trusted embedded create flow via
/embed/create-by-parent/{parentFolderId}with redirect into embed viewer. - External integration APIs:
POST /api/v1/pads/create-by-parent,POST /api/v1/pads/from-template,POST /api/v1/pads/from-url,GET /api/v1/pads/meta-by-id/{fileId}. - Preview provider for
application/x-etherpad-nextcloudreturning the pad-icon as a fallback thumbnail, so the Files app and template picker don't trigger/core/preview4xx responses.
- Architecture cleanup.
PadController(347 LOC, 14 actions, 8 service deps) split intoPadCreateController/PadSessionController/PadLifecycleControllerover a sharedAbstractPadControllerbase — public URL paths unchanged.ExternalPadExportFetcherextracted fromEtherpadClientso the SSRF-hardened external-fetch surface is no longer dragged into services that only need the admin API.PadLifecycleOperationServiceandPadPathServicefolded back into their hosts. Repeated frontmatter-read incantation consolidated into a singlePadFileService::readPadreturning a typedParsedPadFile. - Embedded sync UX: host message hooks for visible/hidden/before-close/sync-now; close-flush ack protocol (
epnc:sync-flush-started|finished|failed); short lock retries for.padsnapshot writes before returningstatus=locked. - Protected pad open is meaningfully faster: earlier iframe start in embed flow, Etherpad author caching per Nextcloud user, author-name sync only on actual display-name changes.
- Fresh
+ → New padno longer logs two 4xx network errors on the first/opencall. The template-flow listener now initialises frontmatter immediately when the user picks theBlankoption, so the very first open returns 200. Two transient artefacts caused by NC's Files-app placeholder rendering (afileId=-1preview 400 and a Tiptap unmount warning) are out-of-scope for this fix and tracked in #72.
- First stable release of Etherpad Integration for Nextcloud.
- Native Nextcloud viewer integration for
.padfiles (authenticated and public-share flows). - Protected/public pad modes with secure session handling for protected pads.
- Admin settings for Etherpad API connection, health check, external public pad policy, and sync interval.
- One-way content sync from Etherpad into
.padsnapshots (automatic while open + manual trigger). - Binding-based lifecycle: delete on Nextcloud trash, restore from Nextcloud trash, deferred retries if Etherpad is temporarily unavailable.
- External public pad linking with HTTPS enforcement and SSRF protection.
- NC30–NC33 compatibility with PHPUnit + E2E release checks.