* feat: make cookie names configurable with prefix setting
Add cookie.prefix setting (default "ep_") that gets prepended to all
cookie names set by Etherpad. This prevents conflicts with other
applications on the same domain that use generic cookie names like
"sessionID" or "token".
Affected cookies: token, sessionID, language, prefs/prefsHttp,
express_sid.
The prefix is passed to the client via clientVars.cookiePrefix in the
bootstrap templates so it's available before the handshake. Server-side
cookie reads fall back to unprefixed names for backward compatibility
during migration.
Fixes#664
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: default cookie prefix to empty string for backward compatibility
Changing the default to "ep_" would invalidate all existing sessions
on upgrade since express-session only looks for the configured cookie
name. Default to "" (no prefix) so upgrades are non-breaking — users
opt-in to prefixed names by setting cookie.prefix in settings.json.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address Qodo review — cookie prefix migration and fallbacks
- l10n.ts: Read prefixed language cookie with fallback to unprefixed
- welcome.ts: Use cookiePrefix for token transfer reads
- timeslider.ts: Use prefix for sessionID in socket messages
- pad_cookie.ts: Fall back to unprefixed prefs cookie for migration
- indexBootstrap.js: Pass cookiePrefix via clientVars to welcome page
- specialpages.ts: Pass settings to indexBootstrap template
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: escape regex metacharacters in cookie prefix, document Vite hardcode
- l10n.ts: Escape special regex characters in cookiePrefix before using
it in RegExp constructor to prevent runtime errors
- padViteBootstrap.js: Add comment noting the hardcoded prefix is
dev-only and must match settings.json
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* security: validate cookie prefix to prevent header injection
Reject cookie.prefix values containing characters outside
[a-zA-Z0-9_-] to prevent HTTP header injection via crafted cookie
names (e.g., \r\n sequences). Falls back to empty prefix with an
error log.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: accessibility — keyboard trap, screen reader support, aria-live
Three accessibility fixes:
#6581 (WCAG 2.1.2 keyboard trap): Escape key now moves focus from the
editor to the first toolbar button, giving keyboard-only users an
escape route. Added a screen-reader-only hint about Escape and Alt+F9.
#7255 (screen reader access): Added role="textbox", aria-multiline="true",
and aria-label="Pad content" to the contenteditable body so screen
readers can identify and interact with the editor content. Fixed
non-standard aria-role="document" to role="document" in pad.html.
#5695 (aria-live character echo): Removed aria-live="assertive" from
every line div in domline.ts. This was causing screen readers to
announce every character typed, overriding users' keyboard echo
settings. The attribute was added in PR #5149 for JAWS compatibility
but aria-live on individual contenteditable lines is a misuse.
Also added .sr-only CSS utility class for visually hidden content.
Fixes#6581, #7255, #5695
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Escape closes gritters first, only exits editor if nothing to dismiss
If gritter popups are visible, Escape closes them and keeps focus in
the editor. Only when there are no popups does Escape move focus to
the toolbar for keyboard trap escape.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address Qodo review — keyboard hint in iframe, aria-readonly
- Move keyboard hint (Escape/Alt+F9) inside the inner iframe with
aria-describedby so screen readers announce it when focusing the
editor. Previously it was on the outer editorcontainer which is a
different document context.
- Set aria-readonly on the editor body when in readonly mode so screen
readers correctly convey editability state.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Enforce 2-space indentation across codebase
Convert all 4-space indented source files to 2-space to match
.editorconfig and project contributor guidelines.
74 files converted: admin UI components, type definitions, security
modules, test files, helpers, and utilities.
No functional changes — 2882 insertions, 2882 deletions (pure
whitespace).
Fixes#7353
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Limit admin tests to chromium and firefox
Webkit is already tested in the dedicated frontend-tests workflow.
Running it again in admin tests causes flaky failures due to slow
socket connections and external API timeouts on webkit CI runners.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: started with implementation
* chore: finished index page
* chore: started with double sided modal
* chore: continue
* chore: completed implementation of transfer token
* chore: fixed typescript checks
* Fix document not scrolling in iOS (all browsers)
This patches a bug where users cannot scroll a document on iOS,
because iOS does not allow iframes to be scrolled.
See https://davidwalsh.name/scroll-iframes-ios for details.
* trigger GitHub actions
---------
Co-authored-by: John McLear <john@mclear.co.uk>
* jQuery: Migrate to `.on()`, `.off()`, `.trigger()`
This avoids methods that are deprecated in newer versions of jQuery.
* jQuery: avoid `.removeAttr`, prefer `.prop`
* helper.edit: wait up to 10 seconds for ACCEPT_COMMIT
* Chat: disabled attribute is boolean
* Chat: avoid inline onclick handler to support jQuery 3.4+
* jQuery: update to version 3.6.0
* Update to 3.7
* Removed deprecated event.
* Revert change to focus on padeditor.ace
---------
Co-authored-by: webzwo0i <webzwo0i@c3d2.de>
Prevent "TypeError: Cannot read properties of null (reading 'sheet')"
exception because google chrome can translate `<style type="text/css" title="dynamicsyntax"></style>` title attribute
The comment "head and body had been removed intentionally" implies
that the tags were causing some sort of problem, but the commit that
removed them (57075d15453331cd1ff6ad1175cb67bd7852d4d2) didn't provide
any rationale. I'm assuming it was a mistake.
* Add the class "pad" to the `<html>` tag in `pad.html` (the outer
iframe's parent).
* Change the CSS selector that refers to the `<html>` tag in
`pad.html` from `html:not(.inner-editor)` to `html.pad`.
* Change the class name of the outer iframe's `<html>` tag from
"inner-editor" to "outer-editor".
* Update CSS rules to use the new class name.