mirror of
https://github.com/ether/etherpad-lite.git
synced 2026-05-05 12:16:45 +02:00
* docs: PR1 GDPR deletion-controls design spec First of five GDPR PRs tracked in #6701. PR1 covers deletion controls: one-time deletion token, allowPadDeletionByAllUsers flag, authorisation matrix for handlePadDelete and the REST deletePad endpoint, a single token-display modal for browser pad creators, and test coverage. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: PR1 GDPR deletion-controls implementation plan 13 TDD-structured tasks covering PadDeletionManager unit tests, socket + REST three-way auth, clientVars wiring, one-time token modal, delete-with-token UI, Playwright coverage, and PR handoff. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gdpr): scaffolding for pad deletion tokens PadDeletionManager stores a sha256-hashed per-pad deletion token and verifies it with timing-safe comparison. createPad / createGroupPad return the plaintext token once on first creation, and Pad.remove() cleans it up. Gated behind the new allowPadDeletionByAllUsers flag which defaults to false to preserve existing behaviour. Part of #6701 (GDPR PR1). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix+test(gdpr): lazy DB access in PadDeletionManager + unit tests Capturing DB.db at module-load time was null until DB.init() ran, which broke importing the module outside a live server (including from the test runner). Switch to DB.db.* at call time and add unit tests exercising create/verify/remove plus timing-safe comparison. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(gdpr): three-way auth for socket PAD_DELETE Creator cookie → valid deletion token → allowPadDeletionByAllUsers flag. Anyone else still gets the existing refusal shout. * feat(gdpr): optional deletionToken on programmatic deletePad * feat(gdpr): advertise optional deletionToken on REST deletePad * test(gdpr): cover deletePad authorisation matrix via REST * feat(gdpr): surface padDeletionToken in clientVars for creators only Revision-0 author on their first CLIENT_READY visit receives the plaintext token; all subsequent CLIENT_READYs receive null because createDeletionTokenIfAbsent is idempotent. Readonly sessions and any other user never see the token. * i18n(gdpr): strings for deletion-token modal and delete-with-token flow * feat(gdpr): token modal + delete-with-token disclosure markup * feat(gdpr): show deletion token once, allow delete via recovery token * style(gdpr): modal + delete-with-token layout * test(gdpr): Playwright coverage for deletion-token modal + delete-with-token * fix(test): auto-dismiss deletion-token modal in goToNewPad helper The token modal introduced in PR1 blocks clicks for every Playwright test that creates a new pad via the shared helper. Add a one-line dismissal so unrelated tests keep passing, and have the deletion-token spec navigate inline via newPadKeepingModal() when it needs the modal open to capture the token. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(test): dismiss deletion-token modal without focus transfer Clicking the ack button transferred focus out of the pad iframe, which made subsequent keyboard-driven tests (Tab / Enter) silently miss the editor. Swap the click for a page.evaluate() that hides the modal and nulls clientVars.padDeletionToken directly, leaving focus where it was. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(gdpr): PadDeletionManager race + document createPad/deletePad Qodo review: - createDeletionTokenIfAbsent() was a non-atomic read-then-write. Two concurrent callers for the same pad could both return different plaintext tokens while only the later hash was stored, leaving the first caller with an unusable recovery token. Serialise per-pad via a Promise chain and add a regression test that fires 8 concurrent calls and asserts exactly one plaintext is emitted and validates. - doc/api/http_api.md now documents createPad returning deletionToken and deletePad accepting the optional deletionToken parameter. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(gdpr): always render delete-with-token in settings popup The rebase onto develop placed the delete-pad-with-token details inside the pad-settings-section conditional, which is only rendered when enablePadWideSettings is true AND the section is toggled visible. Second-device recovery (typing the captured token on a fresh browser) must work without pad-wide settings enabled, so move the details out to sit alongside the existing pad_deletion_token.spec.ts expectations. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(gdpr): require valid token when supplied, gate on auth, harden a11y/i18n - PadMessageHandler: a supplied deletion token must validate; do not fall back to the creator-cookie path when the token is wrong (was deleting the pad anyway when the creator pasted a wrong token into the field). - Skip token issuance + UI when requireAuthentication is on (creator identity is stable, recovery token is redundant noise). - Server emits messageKey instead of hardcoded English; both shout handlers (inline alert and global gritter) localize via html10n. - Suppress the global "Admin message" gritter for pad.deletionToken.* shouts to avoid the "Admin message: undefined" duplicate. - Token-modal a11y: role=dialog, aria-modal, aria-labelledby/describedby, visually-hidden label on the token input, aria-live on Copy, focus to the token input on open and restore on dismiss. - Style the "Delete Pad with Token" disclosure to match the Delete pad button; align the Copy/value row; pad the disclosure label. Tests: Playwright now covers the creator-with-wrong-token path, asserts no "Admin message" / "undefined" gritter on denial; backend API test covers requireAuthentication suppressing the token. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
781 lines
28 KiB
Docker
781 lines
28 KiB
Docker
/**
|
|
* THIS IS THE SETTINGS FILE THAT IS COPIED INSIDE THE DOCKER CONTAINER.
|
|
*
|
|
* By default, some runtime customizations are supported (see the
|
|
* documentation).
|
|
*
|
|
* If you need more control, edit this file and rebuild the container.
|
|
*/
|
|
|
|
/*
|
|
* This file must be valid JSON. But comments are allowed
|
|
*
|
|
* Please edit settings.json, not settings.json.template
|
|
*
|
|
* Please note that starting from Etherpad 1.6.0 you can store DB credentials in
|
|
* a separate file (credentials.json).
|
|
*
|
|
*
|
|
* ENVIRONMENT VARIABLE SUBSTITUTION
|
|
* =================================
|
|
*
|
|
* All the configuration values can be read from environment variables using the
|
|
* syntax "${ENV_VAR}" or "${ENV_VAR:default_value}".
|
|
*
|
|
* This is useful, for example, when running in a Docker container.
|
|
*
|
|
* DETAILED RULES:
|
|
* - If the environment variable is set to the string "true" or "false", the
|
|
* value becomes Boolean true or false.
|
|
* - If the environment variable is set to the string "null", the value
|
|
* becomes null.
|
|
* - If the environment variable is set to the string "undefined", the setting
|
|
* is removed entirely, except when used as the member of an array in which
|
|
* case it becomes null.
|
|
* - If the environment variable is set to a string representation of a finite
|
|
* number, the string is converted to that number.
|
|
* - If the environment variable is set to any other string, including the
|
|
* empty string, the value is that string.
|
|
* - If the environment variable is unset and a default value is provided, the
|
|
* value is as if the environment variable was set to the provided default:
|
|
* - "${UNSET_VAR:}" becomes the empty string.
|
|
* - "${UNSET_VAR:foo}" becomes the string "foo".
|
|
* - "${UNSET_VAR:true}" and "${UNSET_VAR:false}" become true and false.
|
|
* - "${UNSET_VAR:null}" becomes null.
|
|
* - "${UNSET_VAR:undefined}" causes the setting to be removed (or be set
|
|
* to null, if used as a member of an array).
|
|
* - If the environment variable is unset and no default value is provided,
|
|
* the value becomes null. THIS BEHAVIOR MAY CHANGE IN A FUTURE VERSION OF
|
|
* ETHERPAD; if you want the default value to be null, you should explicitly
|
|
* specify "null" as the default value.
|
|
*
|
|
* EXAMPLE:
|
|
* "port": "${PORT:9001}"
|
|
* "minify": "${MINIFY}"
|
|
* "skinName": "${SKIN_NAME:colibris}"
|
|
*
|
|
* Would read the configuration values for those items from the environment
|
|
* variables PORT, MINIFY and SKIN_NAME.
|
|
*
|
|
* If PORT and SKIN_NAME variables were not defined, the default values 9001 and
|
|
* "colibris" would be used.
|
|
* The configuration value "minify", on the other hand, does not have a
|
|
* designated default value. Thus, if the environment variable MINIFY were
|
|
* undefined, "minify" would be null.
|
|
*
|
|
* REMARKS:
|
|
* 1) please note that variable substitution always needs to be quoted.
|
|
*
|
|
* "port": 9001, <-- Literal values. When not using
|
|
* "minify": false substitution, only strings must be
|
|
* "skinName": "colibris" quoted. Booleans and numbers must not.
|
|
*
|
|
* "port": "${PORT:9001}" <-- CORRECT: if you want to use a variable
|
|
* "minify": "${MINIFY:true}" substitution, put quotes around its name,
|
|
* "skinName": "${SKIN_NAME}" even if the required value is a number or
|
|
* a boolean.
|
|
* Etherpad will take care of rewriting it
|
|
* to the proper type if necessary.
|
|
*
|
|
* "port": ${PORT:9001} <-- ERROR: this is not valid json. Quotes
|
|
* "minify": ${MINIFY} around variable names are missing.
|
|
* "skinName": ${SKIN_NAME}
|
|
*
|
|
* 2) Beware of undefined variables and default values: nulls and empty strings
|
|
* are different!
|
|
*
|
|
* This is particularly important for user's passwords (see the relevant
|
|
* section):
|
|
*
|
|
* "password": "${PASSW}" // if PASSW is not defined would result in password === null
|
|
* "password": "${PASSW:}" // if PASSW is not defined would result in password === ''
|
|
*
|
|
* If you want to use an empty value (null) as default value for a variable,
|
|
* simply do not set it, without putting any colons: "${SOFFICE}".
|
|
*
|
|
* 3) if you want to use newlines in the default value of a string parameter,
|
|
* use "\n" as usual.
|
|
*
|
|
* "defaultPadText" : "${DEFAULT_PAD_TEXT:Line 1\nLine 2}"
|
|
*/
|
|
{
|
|
/*
|
|
* Name your instance!
|
|
*/
|
|
"title": "${TITLE:Etherpad}",
|
|
|
|
/*
|
|
* Whether to show recent pads on the homepage or not.
|
|
*/
|
|
"showRecentPads": "${SHOW_RECENT_PADS:true}",
|
|
|
|
/*
|
|
* Pathname of the favicon you want to use. If null, the skin's favicon is
|
|
* used if one is provided by the skin, otherwise the default Etherpad favicon
|
|
* is used. If this is a relative path it is interpreted as relative to the
|
|
* Etherpad root directory.
|
|
*/
|
|
"favicon": "${FAVICON:null}",
|
|
|
|
/*
|
|
* Canonical public origin of this Etherpad instance, e.g.
|
|
* "https://pad.example.com" (no trailing slash, must include scheme).
|
|
* Used to build absolute URLs in OG/Twitter link-preview meta tags.
|
|
* When null, falls back to the incoming request's protocol+Host.
|
|
*/
|
|
"publicURL": "${PUBLIC_URL:null}",
|
|
|
|
/*
|
|
* Skin name.
|
|
*
|
|
* Its value has to be an existing directory under src/static/skins.
|
|
* You can write your own, or use one of the included ones:
|
|
*
|
|
* - "no-skin": an empty skin (default). This yields the unmodified,
|
|
* traditional Etherpad theme.
|
|
* - "colibris": the new experimental skin (since Etherpad 1.8), candidate to
|
|
* become the default in Etherpad 2.0
|
|
*/
|
|
"skinName": "${SKIN_NAME:colibris}",
|
|
|
|
/*
|
|
* Skin Variants
|
|
*
|
|
* Use the UI skin variants builder at /p/test#skinvariantsbuilder
|
|
*
|
|
* For the colibris skin only, you can choose how to render the three main
|
|
* containers:
|
|
* - toolbar (top menu with icons)
|
|
* - editor (containing the text of the pad)
|
|
* - background (area outside of editor, mostly visible when using page style)
|
|
*
|
|
* For each of the 3 containers you can choose 4 color combinations:
|
|
* super-light, light, dark, super-dark.
|
|
*
|
|
* For example, to make the toolbar dark, you will include "dark-toolbar" into
|
|
* skinVariants.
|
|
*
|
|
* You can provide multiple skin variants separated by spaces. Default
|
|
* skinVariant is "super-light-toolbar super-light-editor light-background".
|
|
*
|
|
* For the editor container, you can also make it full width by adding
|
|
* "full-width-editor" variant (by default editor is rendered as a page, with
|
|
* a max-width of 900px).
|
|
*/
|
|
"skinVariants": "${SKIN_VARIANTS:super-light-toolbar super-light-editor light-background}",
|
|
|
|
/*
|
|
* IP and port which Etherpad should bind at.
|
|
*
|
|
* Binding to a Unix socket is also supported: just use an empty string for
|
|
* the ip, and put the full path to the socket in the port parameter.
|
|
*
|
|
* EXAMPLE USING UNIX SOCKET:
|
|
* "ip": "", // <-- has to be an empty string
|
|
* "port" : "/somepath/etherpad.socket", // <-- path to a Unix socket
|
|
*/
|
|
"ip": "${IP:0.0.0.0}",
|
|
"port": "${PORT:9001}",
|
|
|
|
/*
|
|
* Option to hide/show the settings.json in admin page.
|
|
*
|
|
* Default option is set to true
|
|
*/
|
|
"showSettingsInAdminPage": "${SHOW_SETTINGS_IN_ADMIN_PAGE:true}",
|
|
|
|
/*
|
|
* Enable/disable the metrics endpoint.
|
|
*
|
|
* This is used by the monitoring plugins to collect metrics about Etherpad.
|
|
* If you do not use any monitoring plugins, you can disable this.
|
|
*/
|
|
"enableMetrics": "${ENABLE_METRICS:true}",
|
|
|
|
/*
|
|
* Self-update subsystem.
|
|
* tier: "off" | "notify" | "manual" | "auto" | "autonomous"
|
|
* Default "notify" shows a banner when an update is available.
|
|
* Docker installs are read-only — tiers above "notify" are not applied even if requested.
|
|
*/
|
|
"updates": {
|
|
"tier": "notify",
|
|
"source": "github",
|
|
"channel": "stable",
|
|
"installMethod": "docker",
|
|
"checkIntervalHours": 6,
|
|
"githubRepo": "ether/etherpad",
|
|
"requireAdminForStatus": false
|
|
},
|
|
|
|
/*
|
|
* Contact address for admin notifications (updates, security advisories, future features).
|
|
* Set to null to disable outbound mail from the updater.
|
|
*/
|
|
"adminEmail": null,
|
|
|
|
/*
|
|
* Settings for cleanup of pads
|
|
*/
|
|
"cleanup": {
|
|
"enabled": false,
|
|
"keepRevisions": 5
|
|
},
|
|
|
|
/*
|
|
The authentication method used by the server.
|
|
The default value is sso
|
|
If you want to use the old authentication system, change this to apikey
|
|
*/
|
|
"authenticationMethod": "${AUTHENTICATION_METHOD:sso}",
|
|
|
|
/**
|
|
* Allow setting dark mode for the enduser. This is so if the user has preferred dark mode in their browser, Etherpad will respect that.
|
|
* Of course this overrides all the skin variants and the skinName set by the administrator.
|
|
**/
|
|
"enableDarkMode": "${ENABLE_DARK_MODE:true}",
|
|
|
|
/**
|
|
* Enable creator-owned Pad-wide Settings and new-pad default seeding from My View.
|
|
* Disabled by default to preserve the legacy single-settings behavior.
|
|
**/
|
|
"enablePadWideSettings": "${ENABLE_PAD_WIDE_SETTINGS:false}",
|
|
|
|
/*
|
|
* Node native SSL support
|
|
*
|
|
* This is disabled by default.
|
|
* Make sure to have the minimum and correct file access permissions set so
|
|
* that the Etherpad server can access them
|
|
*/
|
|
|
|
/*
|
|
"ssl" : {
|
|
"key" : "/path-to-your/epl-server.key",
|
|
"cert" : "/path-to-your/epl-server.crt",
|
|
"ca": ["/path-to-your/epl-intermediate-cert1.crt", "/path-to-your/epl-intermediate-cert2.crt"]
|
|
},
|
|
*/
|
|
|
|
|
|
/*
|
|
* Enables the use of a different server. We have a different one that syncs changes from the original server.
|
|
* It is hosted on GitHub and should not be blocked by many firewalls.
|
|
* https://etherpad.org/ep_infos
|
|
*/
|
|
|
|
"updateServer": "https://etherpad.org/ep_infos",
|
|
|
|
/*
|
|
* The type of the database.
|
|
*
|
|
* You can choose between many DB drivers, for example: dirty, postgres,
|
|
* sqlite, mysql.
|
|
*
|
|
* You shouldn't use "dirty" for for anything else than testing or
|
|
* development.
|
|
*
|
|
*
|
|
* Database specific settings are dependent on dbType, and go in dbSettings.
|
|
* Remember that since Etherpad 1.6.0 you can also store this information in
|
|
* credentials.json.
|
|
*
|
|
* For a complete list of the supported drivers, please refer to:
|
|
* https://www.npmjs.com/package/ueberdb2
|
|
*/
|
|
|
|
"dbType": "${DB_TYPE:dirty}",
|
|
"dbSettings": {
|
|
"host": "${DB_HOST:undefined}",
|
|
"port": "${DB_PORT:undefined}",
|
|
"database": "${DB_NAME:undefined}",
|
|
"user": "${DB_USER:undefined}",
|
|
"password": "${DB_PASS:undefined}",
|
|
"charset": "${DB_CHARSET:undefined}",
|
|
"filename": "${DB_FILENAME:var/dirty.db}",
|
|
"collection": "${DB_COLLECTION:undefined}",
|
|
"url": "${DB_URL:undefined}"
|
|
},
|
|
|
|
/*
|
|
* The default text of a pad
|
|
*/
|
|
"defaultPadText" : "${DEFAULT_PAD_TEXT:Welcome to Etherpad!\n\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\n\nGet involved with Etherpad at https:\/\/etherpad.org\n}",
|
|
|
|
/*
|
|
* Default Pad behavior.
|
|
*
|
|
* Change them if you want to override.
|
|
*/
|
|
"padOptions": {
|
|
"noColors": "${PAD_OPTIONS_NO_COLORS:false}",
|
|
"showControls": "${PAD_OPTIONS_SHOW_CONTROLS:true}",
|
|
"showChat": "${PAD_OPTIONS_SHOW_CHAT:true}",
|
|
"showLineNumbers": "${PAD_OPTIONS_SHOW_LINE_NUMBERS:true}",
|
|
"useMonospaceFont": "${PAD_OPTIONS_USE_MONOSPACE_FONT:false}",
|
|
"userName": "${PAD_OPTIONS_USER_NAME:null}",
|
|
"userColor": "${PAD_OPTIONS_USER_COLOR:null}",
|
|
"rtl": "${PAD_OPTIONS_RTL:false}",
|
|
"alwaysShowChat": "${PAD_OPTIONS_ALWAYS_SHOW_CHAT:false}",
|
|
"chatAndUsers": "${PAD_OPTIONS_CHAT_AND_USERS:false}",
|
|
"lang": "${PAD_OPTIONS_LANG:null}"
|
|
},
|
|
|
|
/*
|
|
* Pad Shortcut Keys
|
|
*/
|
|
"padShortcutEnabled" : {
|
|
"altF9": "${PAD_SHORTCUTS_ENABLED_ALT_F9:true}", /* focus on the File Menu and/or editbar */
|
|
"altC": "${PAD_SHORTCUTS_ENABLED_ALT_C:true}", /* focus on the Chat window */
|
|
"cmdShift2": "${PAD_SHORTCUTS_ENABLED_CMD_SHIFT_2:true}", /* shows a gritter popup showing a line author */
|
|
"delete": "${PAD_SHORTCUTS_ENABLED_DELETE:true}",
|
|
"return": "${PAD_SHORTCUTS_ENABLED_RETURN:true}",
|
|
"esc": "${PAD_SHORTCUTS_ENABLED_ESC:true}", /* in mozilla versions 14-19 avoid reconnecting pad */
|
|
"cmdS": "${PAD_SHORTCUTS_ENABLED_CMD_S:true}", /* save a revision */
|
|
"tab": "${PAD_SHORTCUTS_ENABLED_TAB:true}", /* indent */
|
|
"cmdZ": "${PAD_SHORTCUTS_ENABLED_CMD_Z:true}", /* undo/redo */
|
|
"cmdY": "${PAD_SHORTCUTS_ENABLED_CMD_Y:true}", /* redo */
|
|
"cmdI": "${PAD_SHORTCUTS_ENABLED_CMD_I:true}", /* italic */
|
|
"cmdB": "${PAD_SHORTCUTS_ENABLED_CMD_B:true}", /* bold */
|
|
"cmdU": "${PAD_SHORTCUTS_ENABLED_CMD_U:true}", /* underline */
|
|
"cmd5": "${PAD_SHORTCUTS_ENABLED_CMD_5:true}", /* strike through */
|
|
"cmdShiftL": "${PAD_SHORTCUTS_ENABLED_CMD_SHIFT_L:true}", /* unordered list */
|
|
"cmdShiftN": "${PAD_SHORTCUTS_ENABLED_CMD_SHIFT_N:true}", /* ordered list */
|
|
"cmdShift1": "${PAD_SHORTCUTS_ENABLED_CMD_SHIFT_1:true}", /* ordered list */
|
|
"cmdShiftC": "${PAD_SHORTCUTS_ENABLED_CMD_SHIFT_C:true}", /* clear authorship */
|
|
"cmdH": "${PAD_SHORTCUTS_ENABLED_CMD_H:true}", /* backspace */
|
|
"ctrlHome": "${PAD_SHORTCUTS_ENABLED_CTRL_HOME:true}", /* scroll to top of pad */
|
|
"pageUp": "${PAD_SHORTCUTS_ENABLED_PAGE_UP:true}",
|
|
"pageDown": "${PAD_SHORTCUTS_ENABLED_PAGE_DOWN:true}"
|
|
},
|
|
|
|
/*
|
|
* Should we suppress errors from being visible in the default Pad Text?
|
|
*/
|
|
"suppressErrorsInPadText": "${SUPPRESS_ERRORS_IN_PAD_TEXT:false}",
|
|
|
|
/*
|
|
* If this option is enabled, a user must have a session to access pads.
|
|
* This effectively allows only group pads to be accessed.
|
|
*/
|
|
"requireSession": "${REQUIRE_SESSION:false}",
|
|
|
|
/*
|
|
* Users may edit pads but not create new ones.
|
|
*
|
|
* Pad creation is only via the API.
|
|
* This applies both to group pads and regular pads.
|
|
*/
|
|
"editOnly": "${EDIT_ONLY:false}",
|
|
|
|
/*
|
|
* If true, all css & js will be minified before sending to the client.
|
|
*
|
|
* This will improve the loading performance massively, but makes it difficult
|
|
* to debug the javascript/css
|
|
*/
|
|
"minify": "${MINIFY:true}",
|
|
|
|
/*
|
|
* How long may clients use served javascript code (in seconds)?
|
|
*
|
|
* Not setting this may cause problems during deployment.
|
|
* Set to 0 to disable caching.
|
|
*/
|
|
"maxAge": "${MAX_AGE:21600}", // 60 * 60 * 6 = 6 hours
|
|
|
|
/*
|
|
* This is the absolute path to the soffice executable.
|
|
*
|
|
* LibreOffice is used for advanced import/export of pads (docx, pdf, odt).
|
|
* Setting it to null disables LibreOffice and will only allow plain text
|
|
* and HTML import/exports.
|
|
*/
|
|
"soffice": "${SOFFICE:null}",
|
|
|
|
/*
|
|
* When true (the default), the "Microsoft Word" export button downloads a .docx file via
|
|
* LibreOffice (requires "soffice" to be set). Set to false to revert to legacy .doc output
|
|
* (which also requires "soffice").
|
|
*/
|
|
"docxExport": "${DOCX_EXPORT:true}",
|
|
|
|
/*
|
|
* txt, doc, docx, rtf, odt, html & htm
|
|
*/
|
|
"allowUnknownFileEnds": "${ALLOW_UNKNOWN_FILE_ENDS:true}",
|
|
|
|
/*
|
|
* This setting is used if you require authentication of all users.
|
|
*
|
|
* Note: "/admin" always requires authentication.
|
|
*/
|
|
"requireAuthentication": "${REQUIRE_AUTHENTICATION:false}",
|
|
|
|
/*
|
|
* Require authorization by a module, or a user with is_admin set, see below.
|
|
*/
|
|
"requireAuthorization": "${REQUIRE_AUTHORIZATION:false}",
|
|
|
|
/*
|
|
* When you use NGINX or another proxy/load-balancer set this to true.
|
|
*
|
|
* This is especially necessary when the reverse proxy performs SSL
|
|
* termination, otherwise the cookies will not have the "secure" flag.
|
|
*
|
|
* The other effect will be that the logs will contain the real client's IP,
|
|
* instead of the reverse proxy's IP.
|
|
*/
|
|
"trustProxy": "${TRUST_PROXY:false}",
|
|
|
|
/*
|
|
* Settings controlling the session cookie issued by Etherpad.
|
|
*/
|
|
"cookie": {
|
|
/*
|
|
* How often (in milliseconds) the key used to sign the express_sid cookie
|
|
* should be rotated. Long rotation intervals reduce signature verification
|
|
* overhead (because there are fewer historical keys to check) and database
|
|
* load (fewer historical keys to store, and less frequent queries to
|
|
* get/update the keys). Short rotation intervals are slightly more secure.
|
|
*
|
|
* Multiple Etherpad processes sharing the same database (table) is
|
|
* supported as long as the clock sync error is significantly less than this
|
|
* value.
|
|
*
|
|
* Key rotation can be disabled (not recommended) by setting this to 0 or
|
|
* null, or by disabling session expiration (see sessionLifetime).
|
|
*/
|
|
// 86400000 = 1d * 24h/d * 60m/h * 60s/m * 1000ms/s
|
|
"keyRotationInterval": "${COOKIE_KEY_ROTATION_INTERVAL:86400000}",
|
|
|
|
/*
|
|
* Value of the SameSite cookie property. "Lax" is recommended unless
|
|
* Etherpad will be embedded in an iframe from another site, in which case
|
|
* this must be set to "None". Note: "None" will not work (the browser will
|
|
* not send the cookie to Etherpad) unless https is used to access Etherpad
|
|
* (either directly or via a reverse proxy with "trustProxy" set to true).
|
|
*
|
|
* "Strict" is not recommended because it has few security benefits but
|
|
* significant usability drawbacks vs. "Lax". See
|
|
* https://stackoverflow.com/q/41841880 for discussion.
|
|
*/
|
|
"sameSite": "${COOKIE_SAME_SITE:Lax}",
|
|
|
|
/*
|
|
* How long (in milliseconds) after navigating away from Etherpad before the
|
|
* user is required to log in again. (The express_sid cookie is set to
|
|
* expire at time now + sessionLifetime when first created, and its
|
|
* expiration time is periodically refreshed to a new now + sessionLifetime
|
|
* value.) If requireAuthentication is false then this value does not really
|
|
* matter.
|
|
*
|
|
* The "best" value depends on your users' usage patterns and the amount of
|
|
* convenience you desire. A long lifetime is more convenient (users won't
|
|
* have to log back in as often) but has some drawbacks:
|
|
* - It increases the amount of state kept in the database.
|
|
* - It might weaken security somewhat: The cookie expiration is refreshed
|
|
* indefinitely without consulting authentication or authorization
|
|
* hooks, so once a user has accessed a pad, the user can continue to
|
|
* use the pad until the user leaves for longer than sessionLifetime.
|
|
* - More historical keys (sessionLifetime / keyRotationInterval) must be
|
|
* checked when verifying signatures.
|
|
*
|
|
* Session lifetime can be set to infinity (not recommended) by setting this
|
|
* to null or 0. Note that if the session does not expire, most browsers
|
|
* will delete the cookie when the browser exits, but a session record is
|
|
* kept in the database forever.
|
|
*/
|
|
// 864000000 = 10d * 24h/d * 60m/h * 60s/m * 1000ms/s
|
|
"sessionLifetime": "${COOKIE_SESSION_LIFETIME:864000000}",
|
|
|
|
/*
|
|
* How long (in milliseconds) before the expiration time of an active user's
|
|
* session is refreshed (to now + sessionLifetime). This setting affects the
|
|
* following:
|
|
* - How often a new session expiration time will be written to the
|
|
* database.
|
|
* - How often each user's browser will ping the Etherpad server to
|
|
* refresh the expiration time of the session cookie.
|
|
*
|
|
* High values reduce the load on the database and the load from browsers,
|
|
* but can shorten the effective session lifetime if Etherpad is restarted
|
|
* or the user navigates away.
|
|
*
|
|
* Automatic session refreshes can be disabled (not recommended) by setting
|
|
* this to null.
|
|
*/
|
|
// 86400000 = 1d * 24h/d * 60m/h * 60s/m * 1000ms/s
|
|
"sessionRefreshInterval": "${COOKIE_SESSION_REFRESH_INTERVAL:86400000}"
|
|
},
|
|
|
|
/*
|
|
* Controls what Etherpad writes to its logs about client IP addresses.
|
|
* Allowed values: "anonymous" (default), "truncated", "full".
|
|
* See settings.json.template for details.
|
|
*/
|
|
"ipLogging": "${IP_LOGGING:anonymous}",
|
|
|
|
/*
|
|
* Deprecated — use `ipLogging` above. Still honoured for one release
|
|
* cycle: true → "anonymous", false → "full".
|
|
*/
|
|
"disableIPlogging": "${DISABLE_IP_LOGGING:false}",
|
|
|
|
/*
|
|
* Allow any user who can edit a pad to delete it without the one-time pad
|
|
* deletion token. If false, only the original creator's author cookie or the
|
|
* deletion token can delete the pad.
|
|
*/
|
|
"allowPadDeletionByAllUsers": "${ALLOW_PAD_DELETION_BY_ALL_USERS:false}",
|
|
|
|
/*
|
|
* Time (in seconds) to automatically reconnect pad when a "Force reconnect"
|
|
* message is shown to user.
|
|
*
|
|
* Set to 0 to disable automatic reconnection.
|
|
*/
|
|
"automaticReconnectionTimeout": "${AUTOMATIC_RECONNECTION_TIMEOUT:0}",
|
|
|
|
/*
|
|
* By default, when caret is moved out of viewport, it scrolls the minimum
|
|
* height needed to make this line visible.
|
|
*/
|
|
"scrollWhenFocusLineIsOutOfViewport": {
|
|
|
|
/*
|
|
* Percentage of viewport height to be additionally scrolled.
|
|
*
|
|
* E.g.: use "percentage.editionAboveViewport": 0.5, to place caret line in
|
|
* the middle of viewport, when user edits a line above of the
|
|
* viewport
|
|
*
|
|
* Set to 0 to disable extra scrolling
|
|
*/
|
|
"percentage": {
|
|
"editionAboveViewport": "${FOCUS_LINE_PERCENTAGE_ABOVE:0}",
|
|
"editionBelowViewport": "${FOCUS_LINE_PERCENTAGE_BELOW:0}"
|
|
},
|
|
|
|
/*
|
|
* Time (in milliseconds) used to animate the scroll transition.
|
|
* Set to 0 to disable animation
|
|
*/
|
|
"duration": "${FOCUS_LINE_DURATION:0}",
|
|
|
|
/*
|
|
* Flag to control if it should scroll when user places the caret in the
|
|
* last line of the viewport
|
|
*/
|
|
"scrollWhenCaretIsInTheLastLineOfViewport": "${FOCUS_LINE_CARET_SCROLL:false}",
|
|
|
|
/*
|
|
* Percentage of viewport height to be additionally scrolled when user
|
|
* presses arrow up in the line of the top of the viewport.
|
|
*
|
|
* Set to 0 to let the scroll to be handled as default by Etherpad
|
|
*/
|
|
"percentageToScrollWhenUserPressesArrowUp": "${FOCUS_LINE_PERCENTAGE_ARROW_UP:0}"
|
|
},
|
|
|
|
/*
|
|
* User accounts. These accounts are used by:
|
|
* - default HTTP basic authentication if no plugin handles authentication
|
|
* - some but not all authentication plugins
|
|
* - some but not all authorization plugins
|
|
*
|
|
* User properties:
|
|
* - password: The user's password. Some authentication plugins will ignore
|
|
* this.
|
|
* - is_admin: true gives access to /admin. Defaults to false. If you do not
|
|
* uncomment this, /admin will not be available!
|
|
* - readOnly: If true, this user will not be able to create new pads or
|
|
* modify existing pads. Defaults to false.
|
|
* - canCreate: If this is true and readOnly is false, this user can create
|
|
* new pads. Defaults to true.
|
|
*
|
|
* Authentication and authorization plugins may define additional properties.
|
|
*
|
|
* WARNING: passwords should not be stored in plaintext in this file.
|
|
* If you want to mitigate this, please install ep_hash_auth and
|
|
* follow the section "secure your installation" in README.md
|
|
*/
|
|
|
|
"users": {
|
|
"admin": {
|
|
// 1) "password" can be replaced with "hash" if you install ep_hash_auth
|
|
// 2) please note that if password is null, the user will not be created
|
|
"password": "${ADMIN_PASSWORD:null}",
|
|
"is_admin": true
|
|
},
|
|
"user": {
|
|
// 1) "password" can be replaced with "hash" if you install ep_hash_auth
|
|
// 2) please note that if password is null, the user will not be created
|
|
"password": "${USER_PASSWORD:null}",
|
|
"is_admin": false
|
|
}
|
|
},
|
|
|
|
/*
|
|
* Restrict socket.io transport methods
|
|
*/
|
|
"socketTransportProtocols" : ["websocket", "polling"],
|
|
|
|
"socketIo": {
|
|
/*
|
|
* Maximum permitted client message size (in bytes). This controls the
|
|
* maximum single-message size for socket.io and directly affects large
|
|
* paste operations. All messages from clients that are larger than this
|
|
* will be rejected. Large values make it possible to paste large amounts
|
|
* of text, and plugins may require a larger value to work properly, but
|
|
* increasing the value increases susceptibility to denial of service
|
|
* attacks (malicious clients can exhaust memory).
|
|
*
|
|
* 1MB accommodates large pastes while still preventing abuse.
|
|
*/
|
|
"maxHttpBufferSize": "${SOCKETIO_MAX_HTTP_BUFFER_SIZE:1000000}"
|
|
},
|
|
|
|
/*
|
|
* Allow Load Testing tools to hit the Etherpad Instance.
|
|
*
|
|
* WARNING: this will disable security on the instance.
|
|
*/
|
|
"loadTest": "${LOAD_TEST:false}",
|
|
|
|
/**
|
|
* Disable dump of objects preventing a clean exit
|
|
*/
|
|
"dumpOnUncleanExit": "${DUMP_ON_UNCLEAN_EXIT:false}",
|
|
|
|
/*
|
|
* Disable indentation on new line when previous line ends with some special
|
|
* chars (':', '[', '(', '{')
|
|
*/
|
|
|
|
/*
|
|
"indentationOnNewLine": false,
|
|
*/
|
|
|
|
/*
|
|
* From Etherpad 1.8.3 onwards, import and export of pads is always rate
|
|
* limited.
|
|
*
|
|
* The default is to allow at most 10 requests per IP in a 90 seconds window.
|
|
* After that the import/export request is rejected.
|
|
*
|
|
* See https://github.com/nfriedly/express-rate-limit for more options
|
|
*/
|
|
"importExportRateLimiting": {
|
|
// duration of the rate limit window (milliseconds)
|
|
"windowMs": "${IMPORT_EXPORT_RATE_LIMIT_WINDOW:90000}",
|
|
|
|
// maximum number of requests per IP to allow during the rate limit window
|
|
"max": "${IMPORT_EXPORT_MAX_REQ_PER_IP:10}"
|
|
},
|
|
|
|
/*
|
|
* From Etherpad 1.8.3 onwards, the maximum allowed size for a single imported
|
|
* file is always bounded.
|
|
*
|
|
* File size is specified in bytes. Default is 50 MB.
|
|
*/
|
|
"importMaxFileSize": "${IMPORT_MAX_FILE_SIZE:52428800}", // 50 * 1024 * 1024
|
|
|
|
/*
|
|
* From Etherpad 1.8.5 onwards, when Etherpad is in production mode commits from individual users are rate limited
|
|
*
|
|
* The default is to allow at most 10 changes per IP in a 1 second window.
|
|
* After that the change is rejected.
|
|
*
|
|
* See https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#websocket-single-connection-prevent-flooding for more options
|
|
*/
|
|
"commitRateLimiting": {
|
|
// duration of the rate limit window (seconds)
|
|
"duration": "${COMMIT_RATE_LIMIT_DURATION:1}",
|
|
|
|
// maximum number of changes per IP to allow during the rate limit window
|
|
"points": "${COMMIT_RATE_LIMIT_POINTS:10}"
|
|
},
|
|
|
|
/*
|
|
* Toolbar buttons configuration.
|
|
*
|
|
* Uncomment to customize.
|
|
*/
|
|
|
|
/*
|
|
"toolbar": {
|
|
"left": [
|
|
["bold", "italic", "underline", "strikethrough"],
|
|
["orderedlist", "unorderedlist", "indent", "outdent"],
|
|
["undo", "redo"],
|
|
["clearauthorship"]
|
|
],
|
|
"right": [
|
|
["importexport", "timeslider", "savedrevision"],
|
|
["settings", "embed", "home"],
|
|
["showusers"]
|
|
],
|
|
"timeslider": [
|
|
["timeslider_export", "timeslider_returnToPad"]
|
|
]
|
|
},
|
|
*/
|
|
|
|
/*
|
|
* Expose Etherpad version in the web interface and in the Server http header.
|
|
*
|
|
* Do not enable on production machines.
|
|
*/
|
|
"exposeVersion": "${EXPOSE_VERSION:false}",
|
|
|
|
/*
|
|
* The log level we are using.
|
|
*
|
|
* Valid values: DEBUG, INFO, WARN, ERROR
|
|
*/
|
|
"loglevel": "${LOGLEVEL:INFO}",
|
|
|
|
/* Override any strings found in locale directories */
|
|
"customLocaleStrings": {},
|
|
|
|
/* Disable Admin UI tests */
|
|
"enableAdminUITests": false,
|
|
|
|
/*
|
|
* Enable/Disable case-insensitive pad names.
|
|
*/
|
|
"lowerCasePadIds": "${LOWER_CASE_PAD_IDS:false}",
|
|
"sso": {
|
|
"issuer": "${SSO_ISSUER:http://localhost:9001}",
|
|
"clients": [
|
|
{
|
|
"client_id": "${ADMIN_CLIENT:admin_client}",
|
|
"client_secret": "${ADMIN_SECRET:admin}",
|
|
"grant_types": ["authorization_code"],
|
|
"response_types": ["code"],
|
|
"redirect_uris": ["${ADMIN_REDIRECT:http://localhost:9001/admin/}"]
|
|
},
|
|
{
|
|
"client_id": "${USER_CLIENT:user_client}",
|
|
"client_secret": "${USER_SECRET:user}",
|
|
"grant_types": ["authorization_code"],
|
|
"response_types": ["code"],
|
|
"redirect_uris": ["${USER_REDIRECT:http://localhost:9001/}"]
|
|
}
|
|
]
|
|
},
|
|
|
|
/* Set the time to live for the tokens
|
|
This is the time of seconds a user is logged into Etherpad
|
|
"ttl": {
|
|
"AccessToken": 3600,
|
|
"AuthorizationCode": 600,
|
|
"ClientCredentials": 3600,
|
|
"IdToken": 3600,
|
|
"RefreshToken": 86400
|
|
}
|
|
*/
|
|
}
|