mirror of
https://github.com/ether/etherpad-lite.git
synced 2026-07-17 16:47:05 +00:00
* docs: design spec for #7524 drop swagger-ui + privacy opt-outs Three-deliverable plan: vendor RapiDoc to replace swagger-ui-express (Scarf-injecting), add privacy.updateCheck and privacy.pluginCatalog opt-outs for our two outbound calls, and ship PRIVACY.md as a public stance doc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: implementation plan for #7524 swagger-ui + privacy opt-outs Twelve TDD-flavoured tasks: privacy settings shape, UpdateCheck + installer opt-outs (each with a failing-test-first cycle), admin backend/UI plumbing, dependency drop, vendored RapiDoc, PRIVACY.md, final verification matrix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(privacy): add privacy block to settings shape Adds privacy.updateCheck and privacy.pluginCatalog, both defaulting to true so behavior is unchanged until operators opt out. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(privacy): honour privacy.updateCheck=false in UpdateCheck check() and getLatestVersion() now early-return when the setting is off. Logs once on first skip. The admin "update available" panel already tolerates an undefined latestVersion. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(privacy): honour privacy.pluginCatalog=false in installer Extracts the gate into pluginCatalogGuard.ts so it can be unit-tested under vitest without dragging in the CJS require() chain from installer.ts. getAvailablePlugins() now throws the tagged disabled error before any fetch. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(privacy): emit results:catalogDisabled when pluginCatalog off Short-circuits the four catalog-driven socket events. The install/ uninstall events are untouched so operators can still install by plugin name even when the catalog is disabled. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(bin): stalePlugins reads updateServer and honours privacy flag Was hardcoding static.etherpad.org and ignoring opt-out. Now exits 0 cleanly when privacy.pluginCatalog=false. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(settings): document privacy block in settings template Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(api-docs): replace swagger-ui-express with RapiDoc shell Drops the swagger-ui-express dep (third-party Scarf telemetry pixel, see swagger-api/swagger-ui#10573) and serves /api-docs with a static HTML shell that mounts <rapi-doc>. /api-docs.json is unchanged. The vendored RapiDoc asset is added in the next commit so the tree is broken for one diff hunk — pair this with the rapidoc-min.js commit during review. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(api-docs): vendor RapiDoc 9.3.4 (MIT) as static asset Pinned bundle with checksum in VERSION. Replaces swagger-ui-dist which shipped a Scarf telemetry pixel. Disables RapiDoc's bundled Google Fonts request via load-fonts="false" plus explicit regular-font/mono-font system stacks — RapiDoc's CSS @font-face rules would otherwise fetch Open Sans from fonts.gstatic.com at render time. Also fixes the /api-docs route's res.sendFile to use an absolute path resolved via settings.root (the previous {root: 'src/static'} was resolved from CWD which is already src/, producing src/src/static). Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(admin): banner when plugin catalog is disabled Subscribes to results:catalogDisabled and renders a localized info banner on the plugins page. install/uninstall still function via CLI. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: PRIVACY.md and README/CHANGELOG pointers Publishes Etherpad's stance on telemetry: two documented, opt-out outbound calls; no third-party analytics; no install-time phone-homes in our deps. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(admin): await checkPluginForUpdates and emit array on error Qodo flagged that checkUpdates emitted the unresolved Promise (missing await) and emitted {} for updatable on the error path, both breaking the admin UI's expected string[] shape. Pre-existing bug surfaced when the surrounding block was edited for the privacy.pluginCatalog gate. Refs #7524 * feat(api-docs): swap RapiDoc for Scalar (actively maintained) Per @SamTV12345's review on #7757: RapiDoc has been effectively unmaintained for a while. Scalar (https://github.com/scalar/scalar) is MIT-licensed, actively developed, and ships a self-contained standalone bundle that works the same way for our purposes. Privacy posture is preserved by configuring the embed: - withDefaultFonts: false (no fonts.scalar.com woff2 fetch) - telemetry: false (defensive) - agent.disabled: true (no api.scalar.com/vector/* calls) - mcp.disabled: true (no MCP integration) - showDeveloperTools: 'never' - hideClientButton: true Verified with headless Chromium: page loads /api-docs, mounts Scalar, renders the Etherpad OpenAPI document, and makes zero requests to any host other than localhost. Vendor: - src/static/vendor/scalar/standalone.js (@scalar/api-reference 1.57.2) - src/static/vendor/scalar/VERSION (sha256 pinned) - src/static/vendor/scalar/LICENSE (MIT) Removed: - src/static/vendor/rapidoc/* Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
68 lines
2.5 KiB
Markdown
68 lines
2.5 KiB
Markdown
# Privacy in Etherpad
|
|
|
|
## What this document is
|
|
|
|
A complete, current list of every network call Etherpad's own code makes
|
|
to a third party, plus how to turn each one off. Plugins are out of
|
|
scope — audit any plugin you install.
|
|
|
|
## TL;DR
|
|
|
|
Etherpad ships with two outbound calls to `etherpad.org`. Both are
|
|
documented below. Both can be disabled with a single config value each.
|
|
No analytics, no usage pings, no third-party SDKs at runtime.
|
|
|
|
## Outbound calls
|
|
|
|
### 1. Version check
|
|
|
|
| | |
|
|
|---|---|
|
|
| URL | `https://static.etherpad.org/info.json` (override via `updateServer`) |
|
|
| Frequency | hourly while the server runs |
|
|
| Payload | GET only; `User-Agent: Etherpad/<version>` |
|
|
| Purpose | surface an "update available" notice in the admin panel |
|
|
| Disable | set `privacy.updateCheck: false` in `settings.json` |
|
|
| Source | `src/node/utils/UpdateCheck.ts` |
|
|
|
|
### 2. Plugin catalog
|
|
|
|
| | |
|
|
|---|---|
|
|
| URL | `https://static.etherpad.org/plugins.json` (override via `updateServer`) |
|
|
| Frequency | on admin-plugins page load (cached 10 min) |
|
|
| Payload | GET only; same `User-Agent` |
|
|
| Purpose | list installable `ep_*` plugins in the admin UI |
|
|
| Disable | set `privacy.pluginCatalog: false` in `settings.json` (manual install via CLI still works) |
|
|
| Source | `src/static/js/pluginfw/installer.ts` |
|
|
|
|
## What we removed
|
|
|
|
`swagger-ui-express` was dropped because the upstream npm package
|
|
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` is now served by a vendored copy of [Scalar](https://github.com/scalar/scalar)
|
|
(MIT) with no outbound calls. The shell explicitly opts out of Scalar's
|
|
default font fetch (`withDefaultFonts: false`) and analytics
|
|
(`telemetry: false`), and pins a system-font stack via CSS.
|
|
|
|
`@scarf/scarf` is listed under `ignoredBuiltDependencies` in
|
|
`pnpm-workspace.yaml`, so its postinstall pixel is suppressed even if a
|
|
future transitive dep pulls Scarf in.
|
|
|
|
## What we will not add
|
|
|
|
- usage analytics or telemetry SDKs
|
|
- crash reporters that send data without explicit opt-in
|
|
- third-party CDN dependencies at runtime
|
|
- dependencies whose install or runtime phones home
|
|
|
|
## Plugins
|
|
|
|
Third-party plugins are out of this guarantee. Plugins run in your
|
|
Etherpad process with full access; audit any plugin you install.
|
|
|
|
## Reporting
|
|
|
|
Found an outbound call this doc doesn't list? Open an issue with the
|
|
label `privacy`.
|