Lokasi ngalangkungan proxy:   [ UP ]  
[Ngawartoskeun bug]   [Panyetelan cookie]                
Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ether/etherpad
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: ether/etherpad
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: develop
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 8 commits
  • 23 files changed
  • 4 contributors

Commits on May 6, 2026

  1. Merge branch 'master' into develop

    Etherpad Release Bot committed May 6, 2026
    Configuration menu
    Copy the full SHA
    45b000d View commit details
    Browse the repository at this point in the history

Commits on May 7, 2026

  1. fix(7686): username 'false' / 'malformed color: false' for legacy set…

    …tings.json (#7688)
    
    * fix(7686): legacy padOptions.userName/userColor=false breaks pad
    
    Settings.json files generated before December 2021 used `false` as the
    default for these two string options (commit 8c857a8 switched the
    template default to `null` and noted "this change has no effect due to
    a bug in how pad options are processed; that bug will be fixed in a
    future commit" — the follow-up never landed). pad.ts:getParams() then
    runs `false.toString()`, the resulting string "false" passes the
    `!== false` sentinel check at _afterHandshake, and notifyChangeName
    ships USERINFO_UPDATE with name="false" and colorId="false" (clobbered
    via clientVars.userColor). The server's hex regex rejects the colour
    and throws `malformed color: false`; the user sees their name as
    "false" and a white swatch.
    
    Defense in depth:
    - Server: Settings.ts::reloadSettings() coerces legacy boolean false
      to null for padOptions.userName / padOptions.userColor and warns the
      operator, matching the existing disableIPlogging shim pattern.
    - Client: the pad.ts userName / userColor callbacks reject the
      literal "false" string so URL params (?userName=false) and any
      other path that surfaces the sentinel as a string are also no-ops.
    - Backend regression test mirrors the shim and asserts it normalizes
      legacy false, leaves explicit values intact, leaves null untouched,
      does not coerce other padOptions keys, and does not coerce the
      string "false" (that path is the client guard's responsibility).
    
    Closes #7686
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(7686): guard padOptions shim against non-object config (Qodo)
    
    Qodo flagged that storeSettings() will overwrite settings.padOptions
    raw with whatever settings.json supplies — including null, primitives,
    or arrays — which would make the new userName/userColor shim crash on
    property access. Add a shape guard so the shim is a no-op for malformed
    padOptions, and extend the regression test to cover null / primitive /
    array shapes.
    
    This doesn't change which configs work (Pad.ts also assumes padOptions
    is an object and would already crash on a null padOptions when a pad
    is opened) but it stops the shim from being the loud thing in the
    stack trace if someone hits it.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    JohnMcLear and claude authored May 7, 2026
    Configuration menu
    Copy the full SHA
    da87a4f View commit details
    Browse the repository at this point in the history
  2. feat(settings): enable Pad-wide Settings by default; fix misleading m…

    …odal title (#7679)
    
    * feat(settings): enable Pad-wide Settings by default; fix misleading modal title
    
    The creator-owned Pad-wide Settings feature (#7545) shipped behind a flag that
    defaulted to false. With the flag off the modal still rendered an H1 of
    `pad.settings.padSettings` ("Pad-wide Settings") for *every* user, even though
    no pad-wide controls were ever shown. Two readers in different browsers both
    saw "Pad-wide Settings" as the modal title, which looked like a creator-gate
    regression but was just a copy bug.
    
    Two changes:
    
    1. Flip the default of `enablePadWideSettings` to `true` (Settings.ts plus
       both settings templates). With the feature on, the creator (revision-0
       author) gets a real "Pad-wide Settings" section gated by
       `clientVars.canEditPadSettings`, while every other user sees only "User
       Settings" — matching the design intent of #7545. This is a behavior change,
       so the settings comments are expanded to describe what the toggle now does.
    
    2. Drop the conditional H1 in `src/templates/pad.html` and always use
       `pad.settings.title` ("Settings"). Operators who explicitly disable the
       feature shouldn't see a label that lies about a section that isn't
       rendered.
    
    Adds backend regression coverage in `tests/backend/specs/socketio.ts`:
    - Different browsers (different cookie jars => different authorIDs): only the
      first joiner gets `canEditPadSettings: true`.
    - Same browser, two tabs (shared HttpOnly token cookie => same authorID):
      both connections are the same identity, both correctly land on the creator
      path.
    
    * test(settings): regression coverage for the settings modal H1
    
    Asserts the rendered `/p/<id>` HTML always uses
    `data-l10n-id="pad.settings.title"` for the modal heading, regardless of
    `enablePadWideSettings`. Catches a re-introduction of the old conditional
    that printed "Pad-wide Settings" for every user when the feature was off.
    
    Action of Qodo review feedback on PR #7679.
    JohnMcLear authored May 7, 2026
    Configuration menu
    Copy the full SHA
    b751fd7 View commit details
    Browse the repository at this point in the history
  3. fix(docker): share corepack cache so etherpad user can resolve pnpm (#…

    …7689)
    
    * fix(docker): share corepack cache so etherpad user can resolve pnpm (#7687)
    
    PR #7674 switched the Dockerfile from `npm install -g pnpm` to corepack
    and `corepack prepare pnpm@${PnpmVersion} --activate`. The activate step
    runs as root and writes its lastKnownGood pin into `$COREPACK_HOME`,
    which defaults to `~/.cache/node/corepack` — i.e. a per-user path. The
    Dockerfile then drops to `USER etherpad` and later runs
    `bin/installLocalPlugins.sh`, which invokes `pnpm` as etherpad. With an
    empty per-user corepack cache and no shared activation file, corepack
    re-resolves pnpm and (for forks/configs without a `packageManager` pin
    matching the activated version) can fall back to "latest" from the
    registry — pulling `pnpm@10.33.4` instead of the requested 11.x and
    failing the workspace's `engines.pnpm` check.
    
    Pin `COREPACK_HOME=/opt/corepack` and chown it to etherpad after the
    prepare step. Both root and etherpad now share the same lastKnownGood
    file and tarball cache, so etherpad inherits the activated pnpm without
    hitting the registry again.
    
    Verified end-to-end:
    
    - `docker build --target development --build-arg ETHERPAD_LOCAL_PLUGINS=ep_test`
      with a stub local plugin runs `installLocalPlugins.sh` cleanly:
      `Done in 16.6s using pnpm v11.0.6`.
    - `docker run ... pnpm --version` as etherpad reports 11.0.6 from the
      shared cache — no "Unsupported environment" error.
    
    Note: corepack still emits a one-time "about to download" line at
    runtime because `corepack prepare pnpm@11.0.6` resolves to the highest
    matching patch (11.0.8) at build time while the project's
    `packageManager` field pins exactly 11.0.6. That's a follow-up — the
    download succeeds non-interactively and the engine check passes.
    
    Fixes #7687.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * chore(docker): action Qodo PR review (#7687 follow-up)
    
    - Replace hard-coded /opt/corepack with ${COREPACK_HOME} in mkdir/chown
      so the env var stays the single source of truth (Qodo: "COREPACK_HOME
      path duplication").
    
    - Add a build-test-local-plugin job to .github/workflows/docker.yml that
      builds the development target with a stub ETHERPAD_LOCAL_PLUGINS so
      the original failure mode (corepack/pnpm cache invisible across the
      USER switch) cannot silently regress (Qodo: "COREPACK_HOME fix lacks
      test"). The job is small — `docker build` only, no run — and uses the
      shared GHA buildx cache.
    
    Verified: same docker build + `docker run pnpm --version` flow on the
    variable form gives identical output (pnpm 11.0.6 from the etherpad-owned
    cache).
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    JohnMcLear and claude authored May 7, 2026
    Configuration menu
    Copy the full SHA
    fe9727b View commit details
    Browse the repository at this point in the history
  4. fix(7606): sync theme-color meta with client-side dark-mode switch (#…

    …7690)
    
    * fix(7606): sync theme-color meta with client-side dark-mode switch
    
    PR #7636 emits <meta name="theme-color"> server-side from
    settings.skinVariants. That covers operators who hard-code a dark
    toolbar in settings.json, but not the runtime path: pad.ts auto-flips
    the toolbar to super-dark when enableDarkMode is on, the browser
    reports prefers-color-scheme: dark, and no localStorage white-mode
    override is set, plus the user can flip it via #options-darkmode.
    Both paths run skinVariants.updateSkinVariantsClasses(), which until
    now never touched the meta — so dark-mode users kept the light
    #ffffff baseline and saw a white address bar above a dark toolbar
    (stffen on #7606 after 2.7.3).
    
    Push the toolbar-color lookup into updateSkinVariantsClasses so the
    meta tracks every class change: the auto-switch on init, the user
    toggle, and the skinVariants builder. Mirrors the CSS-source-order
    table from src/node/utils/SkinColors.ts (last matching *-toolbar
    token wins). When no meta is present (non-colibris skin, server
    omits it) the helper is a no-op.
    
    Adds Playwright coverage for both paths under
    colorScheme: 'light' (manual toggle) and 'dark' (auto-switch on
    dark-OS clients — the case stffen reported).
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(theme-color): action Qodo PR review
    
    (1) Bug — duplicated toolbar→color table: extract the CSS-source-order
    mapping and the default-color constant into src/static/js/skin_toolbar_colors,
    re-imported by both src/node/utils/SkinColors.ts (server, EJS template
    helper) and src/static/js/skin_variants.ts (client, runtime updates). Lives
    under static/js so the browser bundle can resolve it; server-side imports
    of static/js modules already exist (Changeset, AttributeMap, ImportHtml,
    hooks). One source of truth means a future palette change can no longer
    silently desync the server-rendered baseline meta from the client updates,
    which was the exact regression that brought us here.
    
    (2) Rule violation — 4-space continuation indentation in the new
    Playwright spec: re-indent the themeColor helper and the multiline
    test(...) call to the repo's 2-space rule (.editorconfig).
    
    Existing backend coverage (configuredToolbarColor unit tests + the
    specialpages server-render checks for both pad and timeslider) still
    passes against the refactored helper, so it's regression-locked end to
    end.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    JohnMcLear and claude authored May 7, 2026
    Configuration menu
    Copy the full SHA
    ab0cff4 View commit details
    Browse the repository at this point in the history
  5. feat(socialMeta): settings.socialMeta.description override (#7599 fol…

    …low-up) (#7691)
    
    Issue #7599 follow-up from @stffen: the OG description has no obvious
    settings.json knob and the i18n catalog default is English, but most
    preview crawlers (WhatsApp, Signal, Slack, Telegram, Facebook) don't
    send Accept-Language and so always hit the English fallback regardless
    of how many locale files translate `pad.social.description`.
    
    Keep the i18n catalog as the default source — translatable strings
    belong in locale files, per the original Qodo review on PR #7635 — but
    add an explicit `socialMeta.description` setting that wins when set as
    a non-empty string, regardless of negotiated language. This is the
    lever that fixes the crawler case for non-English instances without
    re-introducing per-language config in settings.json (operators who
    want that still use customLocaleStrings).
    
    - Empty/whitespace overrides are treated as unset (would otherwise
      silently blank the preview).
    - Override is HTML-escaped via the same path as every other value.
    - og:locale stays language-negotiated; only the description is forced.
    - Documented next to publicURL in settings.json.template and
      settings.json.docker (env var SOCIAL_META_DESCRIPTION). The
      customLocaleStrings example now spells out pad.social.description so
      operators discover both routes.
    
    5 new unit specs + 4 new integration specs cover override-wins,
    null/missing fallback, blank-treated-as-unset, and HTML-escaping.
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    JohnMcLear and claude authored May 7, 2026
    Configuration menu
    Copy the full SHA
    90aafb1 View commit details
    Browse the repository at this point in the history
  6. fix(socialMeta): coerced numeric/boolean override silently dropped (#…

    …7692)
    
    * fix(socialMeta): coerced numeric/boolean override silently dropped
    
    Qodo flagged on PR #7691: Settings.coerceValue() turns numeric-looking env
    vars into numbers and "true"/"false" into booleans, so e.g.
    SOCIAL_META_DESCRIPTION="2026" arrives at the resolver as the number 2026.
    The previous resolver gated on `typeof override === 'string'`, so it
    silently fell back to the i18n catalog with no warning — the operator's
    docker config would appear broken.
    
    Accept string|number|boolean and stringify before the empty-check; null /
    undefined / unsupported types still fall through to the catalog. Two new
    unit specs cover the numeric and boolean coercion paths.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(socialMeta): widen description type to match coerced runtime
    
    Action Qodo bug-find: SettingsType.socialMeta.description and
    SocialMetaSettings.description still claimed `string | null`, but
    Settings.coerceValue() can produce number|boolean from env-var-driven
    config — the previous resolver fix was correct at runtime but the type
    mismatch forced `as unknown as string` casts in the new tests.
    
    Widen both declared types to `string | number | boolean | null` to match
    runtime reality, drop the typeof string|number|boolean guards in the
    resolver (the union now narrows automatically) and remove the test casts.
    Behaviour is unchanged.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    JohnMcLear and claude authored May 7, 2026
    Configuration menu
    Copy the full SHA
    a356414 View commit details
    Browse the repository at this point in the history
  7. Configuration menu
    Copy the full SHA
    bcf5c91 View commit details
    Browse the repository at this point in the history
Loading