Poznote 6.81.1-beta
Prerelease, published as a beta so it can be tried without anyone on the :6 or
:latest tag picking it up. It finishes the stylesheet rewrite started in
6.81.0-beta, and closes a stored XSS in the import paths.
✨ New
One palette, so a theme is now a short file
-
Every colour in the app comes from a named token, and a theme is 24 token
overrides instead of a parallel set of rules. Light, dark and black are all
built the same way, and the black theme no longer borrows the dark theme's
greys where it forgot to state its own. -
The logo and the icons are coloured rather than filtered, so they follow the
theme instead of being inverted approximations of it. -
The app ships Inter Light, so the lighter text weight really renders lighter
on the pages that use the shared font file.
🐛 Fixed
- Muted text in the dark theme was brighter than the main text it was supposed
to sit behind. - The icon rail was blue in dark mode and grey in light mode.
- Two animations had been silently replaced by another stylesheet declaring the
same@keyframesname. - The button base style overrode contextual buttons that were meant to look
different. - Some page variables leaked out of the page that declared them and applied
where they were never intended. - Importing an attachments archive exported by Poznote dropped its manifest and
its index page into the attachments directory and counted them as two
imported files. - Pages that load the account database before the configuration could fail
outright, depending on the order the two files were required in.
🔒 Security
Stored XSS through imported content (GHSA-xjh4-q36h-mcvv)
Notes saved through the editor have always been sanitized before storage, but
the paths that bring content in from outside stored what they were given: file
and ZIP import, backup restore, and Git Sync pull. A note carrying a <script>
tag or an inline handler therefore ran in the owner's own session on the next
load, with no click needed, since the app opens the most recently updated note.
All four paths now apply the same policy as the editor, keyed by note type, so
imported and edited notes are held to one rule. Task lists, which are JSON and
never rendered as markup, are passed through untouched.
Content already stored from a previous import is not rewritten by this release.
⚠️ For anyone using the REST API
Routes now answer 404 for an id they cannot see
A route addressing a note, folder, tag or notification that does not exist, or
that belongs to another account, used to answer 200 with {"success": true}:
an UPDATE matching no row reports success just like one that changed
something. No data ever crossed accounts, but the answer was untrue, and on a
shared instance it confirmed that the id was understood. The affected routes are
the folder routes taking an id, the note edit-lock routes, the reminder and
notification routes, and tag rename and delete. They now answer 404.
POST /api/v1/notes accepts what the documentation describes
tagscan be an array, the wayPUT /notes/{id}/tagsalready took it. A
comma-separated string still works.folderis accepted as the folder path, which is the name the documentation
has always used.folder_namekeeps working as the older spelling.
🧹 Under the hood
- One stylesheet manifest instead of 778 hand-written
<link>tags. - 62 greys became one text scale, 43 became one border scale, and 367
!importantthat were holding nothing up are gone. - A new isolation test suite replays every API route as the wrong account and
requires a refusal with no trace of the owner in the body, and a CI test
requires every web-reachable page to call an authentication gate. vendor.jsonrecords every vendored third-party library, its version and the
checksum of each file, so a question like "are we affected by this advisory"
can be answered by reading one file.- Removed unused vendored files: the Swagger UI ES bundles and the KaTeX
auto-render script, none of which any page loaded.
❤️ Support
Enjoying Poznote? Support its development on Ko-fi ☕
Thanks so much for all who will support my work! 🙏