Etherpad

repository·develop·Indexed 12 days ago

https://github.com/ether/etherpad

A free and open source real-time collaborative editor designed for high-integrity documentation. Version 3.3.3 features authorship attribution, complete revision history, and self-hosted governance. It includes a Vite and React 19 Admin UI, a plugin system with automated checking tools, and supports installation via official APT repositories or .deb packages on Debian, Ubuntu, and Mint.

Tokens
168.7K
Snippets
467
Records
699
Agent score
96%

What's inside Etherpad

  1. Use the Etherpad HTTP API to control pads

    develop

    The Etherpad HTTP API allows external web applications to manage pads, including creating/deleting pads, managing access permissions, and getting/setting pad content. This enables you to integrate Etherpad's real-time editing into your own application (e.g., via an iframe) while maintaining your own user authentication system. You can map your application's users to Etherpad authors or groups via the API.

    Key Capabilities:

    • Create and delete pads.
    • Grant or forbid access to specific pads.
    • Retrieve or update pad content.
    • Map external user IDs to Etherpad authors or groups.

    OpenAPI Definitions: Definitions are available at:

    • /api/openapi.json (latest)
    • /api/{version}/openapi.json (version-specific)
  2. Etherpad Source Tree Overview

    develop

    The Etherpad repository is organized as follows:

    • bin/: Maintenance and build scripts (e.g., run.sh, checkPad.ts, migrateDB.ts).
    • doc/: Documentation in AsciiDoc and Markdown.
    • src/: The core source code.
      • src/node/: Server-side TypeScript code (DB, handlers, hooks, security, etc.).
      • src/static/: Client-side assets (CSS, fonts, images, JS, skins).
      • src/templates/: Server-rendered page templates (using eejs).
      • src/locales/: Translations.
    • var/: Runtime data, such as the dirty.db database file.
    • packaging/: OS/distribution packaging helpers.
  3. Get started with Etherpad

    develop

    Etherpad is a next-generation collaborative document editing platform. It features real-time editing, an extensible plugin framework, real-time chat, rich text editing, multi-language support, and easy installation via Docker.

    To begin using Etherpad, you can follow these primary paths:

    • Installation: Use Docker for a single-command setup.
    • Configuration: Review the configuration documentation to customize your instance.
    • API: Explore the API documentation to integrate or extend Etherpad functionality.
  4. What is ep_layout_trip_wire?

    develop

    ep_layout_trip_wire is a specialized test fixture used exclusively for the Debian package CI (Continuous Integration) process. It is not a production plugin and should not be loaded or installed in any production Etherpad environment.

    Its purpose is to detect regressions in the packaging layout. Specifically, it ensures that symlinks created during the .deb post-installation process (such as /opt/etherpad/src/plugin_packages) do not cause Node.js module resolution errors. If the symlink resolution causes require('ep_etherpad-lite/...') calls to fail with MODULE_NOT_FOUND, this fixture will trigger a test failure.

  5. Understand how Admin Settings are resolved and redacted

    develop

    When the Admin UI loads settings via the settings socket, the server emits a payload containing both the raw file string and a resolved object.

    The resolved object

    The resolved object represents the in-memory settings module after environment variables have been substituted. To protect security, the server runs this object through a redactor that replaces sensitive paths with the sentinel string "[REDACTED]".

    Redacted Paths

    The following JSON paths are automatically redacted from the resolved payload:

    PathDescription
    users.*.passwordPlaintext basic-auth password
    users.*.passwordHashBcrypt hash
    users.*.hashLegacy credential spelling
    dbSettings.passwordDatabase password (mysql/postgres/redis)
    dbSettings.userDatabase username
    sso.clients[*].client_secretOIDC client secret
    sso.clients[*].secretLegacy OIDC secret spelling
    sso.issuerSSO Issuer (if URL contains userinfo credentials)
    loadTest.*.passwordep_load_test credentials
    sessionKeySession signing material

    Important: dbSettings.filename is not redacted, allowing operators to verify volume mounts.

  6. Token Resolution Order in Socket.io Handshake

    develop

    When a client connects via Socket.io and sends a CLIENT_READY message, the server resolves the author identity using the following priority order:

    1. Cookie (Primary): The value found in socket.request.cookies[${cp}token] or cookies.token.
    2. Legacy Payload (Fallback): The token field provided within the message.token payload.
      • Note: Using this path triggers a one-time warning: “client is still sending token; cookie migration will take effect on next HTTP response”.
      • The session is flagged with session.legacyToken = true to trigger a cookie rewrite on the next Express middleware hit.
    3. Refusal: If neither is present, the connection is refused.
  7. Audit third-party plugins for privacy

    develop

    The privacy guarantees provided by Etherpad core (no analytics, no usage pings, no third-party SDKs) do not apply to plugins.

    Because plugins run within the Etherpad process with full access, you must manually audit any plugin you install to ensure it does not make unauthorized outbound network calls or collect data.

  8. Understand Admin UI socket behavior when plugin catalog is disabled

    develop

    When settings.privacy.pluginCatalog is set to false, the following behaviors occur in the Admin UI via the socket handlers:

    • getInstalled: The updatable property on installed plugins will remain undefined, so no "update available" badges are rendered.
    • checkUpdates: The server emits results:catalogDisabled and stops processing.
    • getAvailable: The server emits results:catalogDisabled and stops processing.
    • search: The server emits results:catalogDisabled and stops processing.
  9. Understand the native DOCX and PDF export/import behavior

    develop

    Etherpad uses a soffice-presence-driven selection model for document export. There is no explicit opt-in flag; the system automatically chooses between LibreOffice (soffice) and native JavaScript implementations based on your configuration.

    Export Behavior

    • If settings.soffice is configured: The system uses the existing soffice path (LibreOffice).
    • If settings.soffice is 'withoutPDF' (Windows): The system uses soffice for most formats but falls back to native implementation for pdf.
    • If settings.soffice is null (or 'no'): The system uses native JavaScript implementations:
      • DOCX: Uses html-to-docx.
      • PDF: Uses a custom pdfkit + htmlparser2 walker.
      • Note: odt and doc formats remain blocked in this mode.

    Import Behavior

    • DOCX Import: When settings.soffice is null, Etherpad uses mammoth to perform native DOCX imports in-process.

    Security Note

    To prevent SSRF (Server-Side Request Forgery) during conversion, all HTML is processed through a stripRemoteImages sanitizer. This removes any <img> tags with remote URLs, allowing only data: URIs or relative paths before the content reaches the DOCX or PDF converters.

  10. Embed the Etherpad timeslider in your own page

    develop

    Since Etherpad 2.7, the timeslider is rendered in-place inside the pad page. If you want to embed the timeslider in your own external page, use the following URL format which serves the full timeslider HTML:

    /p/:padid/timeslider?embed=1

  11. Understand the Etherpad database schema and key structures

    develop

    Etherpad uses a key-value database structure to manage pads, revisions, chat entries, users, and sessions. Understanding these keys is essential for interacting with the data layer or performing migrations.

    Pad Data

    • pad:$PADID: The primary record for a pad. It contains the latest attributed text (atext), the attribute pool (pool), the latest revision number (head), the latest chat entry number (chatHead), a public security flag, and the passwordHash (salted sha512).
    • pad:$PADID:revs:$REVNUM: Stores a specific revision of a pad. It includes meta (author and timestamp) and the changeset.
    • pad:$PADID:chat:$CHATNUM: Stores a specific chat entry, including the text, userId, and time.

    User and Group Management

    • globalAuthor:$AUTHORID: Stores author metadata like name and colorID.
    • groups: A JSON object mapping groupIDs to 1.
    • group:$GROUPID: Contains a pads object mapping pad names to 1.
    • mapper2group:$MAPPER and mapper2author:$MAPPER: Used to map external application identifiers to internal Etherpad groups or authors.

    Session Management

    • session:$SESSIONID: Represents a session between an author and a group. Contains groupID, authorID, and validUntil (timestamp).
    • author2sessions:$AUTHORID: Maps an author to their active sessionsIDs.
    • group2sessions:$GROUPID: Maps a group to its active sessionsIDs.

    ID Translation

    • pad2readonly:$PADID: Maps a padID to a readonlyID.
    • readonly2pad:$READONLYID: Maps a readonlyID back to a padID.
    • token2author:$TOKENID: Maps an authentication token to an authorID.
  12. Understand the Admin /settings parsed view design

    develop

    The /admin/settings page in Etherpad provides two ways to manage settings.json:

    1. Form View: A parsed, tree-based UI that renders each JSON key as a typed widget (e.g., StringInput, BooleanToggle, NumberInput). It surfaces leading comments as inline help text and displays ${VAR:default} environment placeholders as read-only EnvPill components.
    2. Raw View: A standard <textarea> for power users to perform structural edits, such as adding or removing keys, which are not supported in Form mode.

    Both views share the same single source of truth: the raw file text. The system uses jsonc-parser to perform surgical edits on the text to ensure that untouched regions (comments, whitespace, key order, and environment placeholders) remain byte-identically preserved for Git tracking.