- add app/proxy/vaultProxyGuard.js: inspects proxied note writes and
deletes before forwarding to upstream Joplin Server
- covers single PUT /api/items/root:/<id>.md:/content, batch PUT
/api/batch_items, single DELETE, and batch DELETE
- rejects with 403 when a vault note body lacks the encrypted marker,
or when a vault note is deleted via the sync proxy
- bodies over 10 MB stream through without inspection (resource blobs)
- unauthenticated requests stream through (upstream handles 401)
- wire guard into createServer.js proxy entry point; replay buffered
body via Readable.from() on allow
- 34 new unit tests, all 394 tests passing
Register BASIC with highlight.js (preview mode) and add it to the
code modal language picker. CodeMirror falls back to plain text in
the modal editor as no CM6 BASIC parser is available.
Use the shared title sanitizer for both SSR and client-side title editing
so note titles are cleaned by one function. Also sanitize note titles on
create in the fragments route and add a regression test for formatted
titles.
syncResponsiveMode already called redrawMobileUI() when crossing
desktop→mobile, but the reverse path only hid the mobile app. A session
that started narrow (mobile mode) never called initNavPanel/initEditorPanel
for the desktop form, leaving the preview and CM host with undefined
display states and stale scroll position.
Mirror the pattern: save wasMobile before clobbering _lastSyncWasMobile,
then call initNavPanel()+initEditorPanel() when wasMobile===true.
Both functions are idempotent (guarded by dataset flags) so a repeat
call on an already-initialised form is a no-op.
- Install markdown-it@14.1.1 as server-side renderer (renderMarkdown only)
- Preserve all Joplin extensions: underline (++..++), checkboxes,
blank-line markers, softbreak→<br>, resource URIs, spellcheck attrs,
hx-* strip, fence/code/image/link render overrides
- Fix blank-line round-trip: emptyDiv/emptyP Turndown rules now return
the BL sentinel instead of '<br>' (which line 611 inflated to 4 newlines)
or '' (which made blank-line edits never save)
- Disable CSS scroll anchoring in preview editor so images flow down
naturally when text is typed above them
- Narrow the Notebook + button label and padding in the nav header
- Bump static asset version to 20260501a
Custom regex renderer's fence extraction required column-0 anchoring,
so any fence inside a list item (or with leading whitespace) was missed
and the loose backticks were mangled by the inline-code regex. Add a
list-item-nested fence pass that outdents the body and preserves the
surrounding list structure as a placeholder, plus relax the column-0
fence regex to allow up to 3 spaces of indentation per CommonMark and
trailing whitespace on the closing fence.
Eliminates fragile ad-hoc DOM toggling that allowed two mobile screens to
render simultaneously. All transitions now go through setMobileState()
reducer; renderMobile() is the only function that writes
.mobile-screen-active. assertSingleActiveScreen() self-heals violations
and traces them. Test asserts the architectural invariant in source.
Also: DB session lookup fails closed on transient errors instead of
crashing; mobile back-save uses formHash (not UI badge); single-screen
CSS via display:none/flex (no transforms); resize debounced without
reload; aria-hidden warning fix.