fix(admin): honour escape sequences in settings form string fields - #8239
JohnMcLear wants to merge 3 commits into
Conversation
The settings form view rendered string values in single-line <input>s. Browsers strip line breaks from an input's value, so values such as defaultPadText lost their newlines, and anything typed (e.g. `\n`) was JSON-encoded again on save, producing `\\n` in settings.json and a literal backslash-n in the pad text. Env placeholder defaults were shown in raw escaped form but re-escaped on save, with the same result. String inputs and env placeholder defaults now show values in their JSON-escaped form and decode typed escape sequences before writing, so `Welcome\n\ntest\n` is stored exactly like a hand-edited settings.json. Incomplete escapes (a trailing backslash while typing) are not propagated. Fixes #8211 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012kA75NPq8nGRidAwhPXeCi
|
ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing |
PR Summary by QodoPreserve escape sequences in admin settings string fields
AI Description
Diagram
High-Level Assessment
Files changed (5)
|
Code Review by Qodo
1.
|
Earlier admin specs rewrite settings.json as minified JSON, so the key is not at the start of a line in CI. Take the last match instead, which also skips the template's documentation comment. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012kA75NPq8nGRidAwhPXeCi
…d braces Address review: EnvPill now marks undecodable drafts aria-invalid and restores the applied value on blur (matching StringInput), and a default whose decoded form contains `}` is rejected/kept raw instead of having the brace silently stripped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012kA75NPq8nGRidAwhPXeCi
Fixes #8211
Root cause
The
/admin/settingsform view edits string values through single-line<input type="text">widgets:StringInput) were shown decoded. Browsers strip line breaks from an input's value, sodefaultPadTextshowed asWelcome to Etherpad!This pad text…. Typing\nwas then JSON-encoded again byjsonc-parser'smodify(), which wrote\\nto settings.json. The pad then showed a literal\n.EnvPill, e.g."${DEFAULT_PAD_TEXT:Line 1\nLine 2}") were shown in raw escaped form, sliced straight from the JSON text, but re-escaped on save. So\nbecame\\n. This is exactly what the issue reports.Raw mode wasn't affected: it sends the textarea text through unchanged.
Fix
admin/src/components/settings/stringEscapes.ts, withescapeForInputandunescapeFromInput.\nand a backslash as\\. Quotes and/stay readable.Welcome\n\ntest\nis saved as"Welcome\n\ntest\n", the same bytes you'd get by editing settings.json by hand.\or\q) isn't saved. The input getsaria-invaliduntil the text decodes, and on blur it resets to the last valid value.Tests
admin/src/components/settings/__tests__/stringEscapes.test.ts) cover escape/unescape, invalid escapes, round-trips, and the jsonc write, checking that the file gets\nand not\\n.pnpm testinadmin/: 27/27 pass.adminsettings.spec.ts(chromium-admin):#8211 … form string field: before the fix it failed withReceived string: "Welcome to Etherpad!This pad text…"(newlines dropped). After the fix it passes: the field shows\n, and a value typed with\n,\\and"round-trips to the expected decoded JSON value.#8211 … env placeholder default: before the fix it failed, and the file contained"defaultPadText": "${DEFAULT_PAD_TEXT:Welcome\\n\\ntest\\n}". After the fix it passes, with${DEFAULT_PAD_TEXT:Welcome\n\ntest\n}.adminsettings.spec.tspasses locally (14/14). I left out the restart tests: on my local server started with--settings <custom path>, the in-process restart reloads without the admin user. That's specific to my setup and unrelated to this change; CI uses the root settings.json.tsc --noEmit: clean. The admin build (tsc && vite build) is clean.🤖 Generated with Claude Code
https://claude.ai/code/session_012kA75NPq8nGRidAwhPXeCi