etherpad-lite/settings.json.template
John McLear 9014d3a7c4
fix(colors): pick WCAG-higher-contrast text for author colors (#7565)
* feat(colors): clamp author backgrounds to WCAG 2.1 AA on render

Fixes #7377.

Authors can pick any color via the color picker, so a user who chooses
a dark red ends up with black text rendered on a background that fails
WCAG 2.1 AA (4.5:1) — unreadable, but there is no way for *viewers* to
remediate since they cannot change another author's color. Screenshot
in the issue shows exactly this.

This PR lands a viewer-side clamp. For each author background, if
neither black nor white text would satisfy the target contrast ratio,
the bg is iteratively blended toward white until black text does. The
author's stored color is untouched — turning off the new
padOptions.enforceReadableAuthorColors flag restores the raw colors
immediately.

New helpers in src/static/js/colorutils.ts:

- relativeLuminance(triple)  — WCAG 2.1 relative-luminance formula
- contrastRatio(c1, c2)      — in [1, 21]; >=4.5 = AA, >=7.0 = AAA
- ensureReadableBackground(hex, minContrast = 4.5)
                             — returns a hex that meets minContrast
                               against black text, preserving hue

Wire-up:

- src/static/js/ace2_inner.ts (setAuthorStyle): pass bgcolor through
  ensureReadableBackground before picking text color. Gated on
  padOptions.enforceReadableAuthorColors (default true). Guarded by
  colorutils.isCssHex so the few non-hex values (CSS vars, etc.) skip
  the clamp and pass through unchanged.
- Settings.ts / settings.json.template / settings.json.docker: new
  padOptions.enforceReadableAuthorColors flag, default true, with a
  matching PAD_OPTIONS_ENFORCE_READABLE_AUTHOR_COLORS env var in the
  docker template.
- doc/docker.md: env-var row.
- src/tests/backend/specs/colorutils.ts: new unit coverage for the
  three new helpers, including the exact #cc0000 failure case from
  the issue screenshot.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(7377): simplify — just pick higher-contrast text, drop bg clamp

First iteration added an iterative bg-lightening helper
(ensureReadableBackground) gated by a new padOptions flag. CI caught the
correct simpler framing: because WCAG contrast is symmetric in [1, 21],
at least one of black/white always clears AA (4.5:1) for any sRGB
colour. The real bug was that the pre-fix textColorFromBackgroundColor
used a plain-luminosity cutoff (< 0.5 → white), which produced
sub-AA combinations like white-on-red (#ff0000) at 4.0:1.

Reduce the PR to the minimal surface:

- colorutils.textColorFromBackgroundColor now picks whichever of
  black/white has the higher WCAG contrast ratio against the bg.
- colorutils.relativeLuminance and colorutils.contrastRatio are kept
  as reusable building blocks; ensureReadableBackground is dropped
  (no caller needed it once text selection was fixed).
- ace2_inner.ts setAuthorStyle no longer needs the opt-in flag or the
  isCssHex guard — the helper handles every input its caller already
  passes.
- padOptions.enforceReadableAuthorColors setting reverted along with
  settings.json.template, settings.json.docker, and doc/docker.md.
- Tests replaced: instead of asserting the bg gets lightened, assert
  that the chosen text colour clears AA for every primary. Covers the
  exact #ff0000 failure case from the issue screenshot.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(7377): assert relative-contrast invariant, not absolute AA

Pure primaries like #ff0000 cannot clear WCAG AA (4.5:1) against either
#222 or #fff — the best either can do is ~4.0:1. No text-colour choice
alone fixes that; bg clamping would be a separate concern. The test
should therefore verify the *real* invariant: the chosen text colour
must produce the higher contrast of the two options, regardless of
whether that contrast clears any absolute threshold.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(7377): compare against rendered #222/#fff, not pure black/white

First cut of textColorFromBackgroundColor computed contrast against
pure black (L=0) and pure white (L=1), then returned the concrete
#222/#fff the pad actually renders with. For some mid-saturation
backgrounds the two comparisons disagreed — e.g. #ff0000:
  vs pure black = 5.25 → pick black → render #222 → actual 3.98
  vs pure white = 4.00 → would-render #fff → actual 4.00
The helper picked the wrong option because it compared against the
wrong target. Compare against the actual rendered colours so the
returned text colour is genuinely the higher-contrast choice.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(7377): pick unambiguous colibris test bgs

#ff0000 lives right at the boundary for the two text choices (4.00 vs
3.98), so the test for colibris-skin mapping was entangled with the
border-case selector pick. Use #ffeedd (clearly light → dark text
wins) and #111111 (clearly dark → light text wins) so the test
isolates the skin mapping from the tie-breaking logic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(7377): use rendered text colour + clamp bg to actually meet AA

Local repro of the issue exposed two real bugs in the previous fix:

1. textColorFromBackgroundColor compared bg against a hardcoded #222 —
   but in the colibris skin --super-dark-color resolves to #485365.
   For the issue's exact case (#9AB3FA author bg) the selector returned
   var(--super-dark-color) thinking it was getting a 7.7:1 ratio, while
   the browser actually rendered 3.78:1 — identical to what the issue
   screenshot reported. This PR's previous behaviour on the issue's
   inputs was unchanged from the pre-fix.

2. For mid-saturation pastels (#9AB3FA) and pure primaries (#ff0000)
   neither rendered dark nor white text can clear AA. Text-colour
   selection alone genuinely cannot fix this band; the ensureReadable
   bg clamp dropped in ce0c5c283 was load-bearing.

Changes:

- colorutils.ts: per-skin SKIN_TEXT_COLORS table with darkRef/lightRef
  matching what the browser actually paints (colibris #485365,
  default #222). Re-introduces ensureReadableBackground, but skin-aware
  and symmetric — blends bg toward white or black depending on which
  text colour wins, so it works for both light and dark backgrounds.
- ace2_inner.ts: setAuthorStyle runs the bg through the clamp before
  picking text colour. Gated on padOptions.enforceReadableAuthorColors
  (default true).
- Settings.ts / settings.json.template / settings.json.docker /
  doc/docker.md: padOption + PAD_OPTIONS_ENFORCE_READABLE_AUTHOR_COLORS
  env var.
- tests: failing-then-green coverage for the issue's exact case
  (#9AB3FA + colibris), the previously-impossible #ff0000, the
  no-mutation case, non-hex pass-through, and a sweep over primaries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(7377): add e2e DOM-contrast spec + extra unit cases

The previous coverage was unit-only, which is what let the original wrong-
reference-colour bug ship — the algorithm tests were green but nothing
exercised what the browser actually paints. New coverage:

Playwright (src/tests/frontend-new/specs/wcag_author_color.spec.ts):
- Sets the user's colour to the issue's exact #9AB3FA, types text, reads
  the rendered author span's computed bg + colour from the inner frame,
  and asserts the WCAG ratio between the two is >= 4.5. Repeated for
  #ff0000 (the other historically-failing case).
- Asserts #ffeedd (already AA-friendly) is rendered unchanged — guards
  against the clamp mutating colours that don't need it.

Backend additions (src/tests/backend/specs/colorutils.ts):
- Symmetric-clamp test: dark mid-saturation bg where light text wins, the
  clamp must darken (not lighten). Direction check via relativeLuminance.
- minContrast parameter: AAA (7.0) must produce more clamping than AA.
- Output shape: result must be a parseable hex string (round-trip safe).
- Short-hex (#abc) input is accepted and normalised.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 12:56:30 +08:00

831 lines
28 KiB
Text

/*
* 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": "Etherpad",
/*
* Whether to show recent pads on the homepage or not.
*/
"showRecentPads": 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": null,
/*
* Canonical public origin of this Etherpad instance, e.g.
* "https://pad.example.com" (no trailing slash, must include scheme).
*
* When set, this is used to build absolute URLs in server-rendered output
* such as the Open Graph / Twitter Card link-preview meta tags (og:url,
* og:image, ...). When null, those URLs fall back to the request's
* protocol+Host, which can reflect client-controlled headers if your
* reverse proxy passes them through unsanitized.
*
* Set this in production deployments to lock down the canonical origin
* advertised in shared link previews.
*/
"publicURL": 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": "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": "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": "0.0.0.0",
"port": 9001,
/*
* Option to hide/show the settings.json in admin page.
*
* Default option is set to true
*/
"showSettingsInAdminPage": 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. "off" disables the version check.
*/
"updates": {
"tier": "notify",
"source": "github",
"channel": "stable",
"installMethod": "auto",
"checkIntervalHours": 6,
"githubRepo": "ether/etherpad",
/*
* Lock /admin/update/status to authenticated admins. Default false keeps the
* endpoint open (the version is already public via /health). Set true to hide
* full update detail from non-admins without turning the updater off.
*/
"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
},
/*
* 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"]
},
*/
/*
* 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": "dirty",
"dbSettings": {
"filename": "var/dirty.db"
},
/*
* An Example of MySQL Configuration (commented out).
*
* See: https://github.com/ether/etherpad/wiki/How-to-use-Etherpad-Lite-with-MySQL
*/
/*
"dbType" : "mysql",
"dbSettings" : {
"user": "etherpaduser",
"host": "localhost",
"port": 3306,
"password": "PASSWORD",
"database": "etherpad_lite_db",
"charset": "utf8mb4"
},
*/
/*
* The default text of a pad
*/
"defaultPadText" : "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": false,
"showControls": true,
"showChat": true,
"showLineNumbers": true,
"useMonospaceFont": false,
"userName": null,
"userColor": null,
"rtl": false,
"alwaysShowChat": false,
"chatAndUsers": false,
"lang": null,
/*
* When true (default), each author's caret/background color fades toward white
* as the author goes inactive. Set to false if users pick light colors and the
* faded variants become visually indistinguishable.
*/
"fadeInactiveAuthorColors": true,
/*
* Clamp author background colors to a WCAG 2.1 AA contrast ratio (4.5:1)
* against the rendered text colour at render time. The author's stored
* colour is not modified — only the displayed shade is adjusted. Set to
* false to render exact author colours regardless of contrast.
*/
"enforceReadableAuthorColors": true
},
/*
* Pad Shortcut Keys
*/
"padShortcutEnabled" : {
"altF9": true, /* focus on the File Menu and/or editbar */
"altC": true, /* focus on the Chat window */
"cmdShift2": true, /* shows a gritter popup showing a line author */
"delete": true,
"return": true,
"esc": true, /* in mozilla versions 14-19 avoid reconnecting pad */
"cmdS": true, /* save a revision */
"tab": true, /* indent */
"cmdZ": true, /* undo/redo */
"cmdY": true, /* redo */
"cmdI": true, /* italic */
"cmdB": true, /* bold */
"cmdU": true, /* underline */
"cmd5": true, /* strike through */
"cmdShiftL": true, /* unordered list */
"cmdShiftN": true, /* ordered list */
"cmdShift1": true, /* ordered list */
"cmdShiftC": true, /* clear authorship */
"cmdH": true, /* backspace */
"ctrlHome": true, /* scroll to top of pad */
"pageUp": true,
"pageDown": true
},
/*
* 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",
/*
* Should we suppress errors from being visible in the default Pad Text?
*/
"suppressErrorsInPadText": 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": 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": 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": 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": 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": 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": true,
/*
* txt, doc, docx, rtf, odt, html & htm
*/
"allowUnknownFileEnds": true,
/*
* This setting is used if you require authentication of all users.
*
* Note: "/admin" always requires authentication.
*/
"requireAuthentication": false,
/*
* Require authorization by a module, or a user with is_admin set, see below.
*/
"requireAuthorization": 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": false,
/*
* Settings controlling the session cookie issued by Etherpad.
*/
"cookie": {
/*
* Prefix for all cookie names set by Etherpad. Set this to "ep_" or similar
* if Etherpad's cookie names (token, sessionID, etc.) conflict with those
* of another application on the same domain. Default: "" (no prefix).
*/
// "prefix": "ep_",
/*
* 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).
*/
"keyRotationInterval": 86400000, // = 1d * 24h/d * 60m/h * 60s/m * 1000ms/s
/*
* 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": "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.
*/
"sessionLifetime": 864000000, // = 10d * 24h/d * 60m/h * 60s/m * 1000ms/s
/*
* 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.
*/
"sessionRefreshInterval": 86400000, // = 1d * 24h/d * 60m/h * 60s/m * 1000ms/s
/*
* Whether to periodically clean up expired and stale sessions from the
* database. Set to false to disable. Default: true.
*/
"sessionCleanup": true
},
/*
* Controls what Etherpad writes to its logs about client IP addresses.
*
* "anonymous" — replace every IP with the literal "ANONYMOUS" (default)
* "truncated" — zero the last octet of IPv4 (1.2.3.0); truncate IPv6 to
* the first /48 (2001:db8:1::). Keeps aggregate visibility.
* "full" — log the full IP (document a legal basis + retention
* policy before choosing this).
*
* In-memory rate-limiting always keys on the raw IP and is never persisted.
*/
"ipLogging": "anonymous",
/*
* Deprecated — use `ipLogging` above instead. Still honoured for one release
* cycle: `true` maps to `ipLogging: "anonymous"`, `false` maps to `"full"`.
* A deprecation warning is emitted when only this legacy setting is present.
*/
"disableIPlogging": 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": 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": 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": 0,
"editionBelowViewport": 0
},
/*
* Time (in milliseconds) used to animate the scroll transition.
* Set to 0 to disable animation
*/
"duration": 0,
/*
* Flag to control if it should scroll when user places the caret in the
* last line of the viewport
*/
"scrollWhenCaretIsInTheLastLineOfViewport": 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": 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": "changeme1",
"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": "changeme1",
"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": 1000000
},
/*
* Allow Load Testing tools to hit the Etherpad Instance.
*
* WARNING: this will disable security on the instance.
*/
"loadTest": false,
/**
* Disable dump of objects preventing a clean exit
*/
"dumpOnUncleanExit": 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": 90000,
// maximum number of requests per IP to allow during the rate limit window
"max": 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": 52428800, // 50 * 1024 * 1024
/*
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}",
/*
* 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": 1,
// maximum number of changes per IP to allow during the rate limit window
"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": false,
/*
* The log level we are using.
*
* Valid values: DEBUG, INFO, WARN, ERROR
*/
"loglevel": "INFO",
/*
* The log layout type to use.
*
* Valid values: basic, colored
*/
"logLayoutType": "colored",
/* Override any strings found in locale directories */
"customLocaleStrings": {},
/* Disable Admin UI tests */
"enableAdminUITests": false,
/*
* Enable/Disable case-insensitive pad names.
*/
"lowerCasePadIds": 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
}
*/
}