- Fjord (new), Polarized Hell and Suri Hell complete the families
Klassik, Fjord, Terrakotta, Polarized, Suri
- settings: family table, follow-system, corners, button frames and an own
accent colour (per device); compact quick picker in the user menus
- code colours in index.css are fallbacks only
chore(release): v0.14.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- VAPID keys from VAPID_* or generated once (push_keys, migration 9);
devices in push_subscriptions, forgotten on 404/410 from the push service
- push column for every event (also due tasks) and the daily summary,
bundles as one notification; /push/key, /devices, /subscribe,
/unsubscribe, /test
- settings: switch push on per device, test it, see the devices; the
service worker shows notifications and focuses MindSift on click
- tests decrypt a sent push like a browser (RFC 8291) and check VAPID
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- journal_days (migration 8) maps a person's day to an ordinary note;
GET /journal lists the days, POST /journal/{date} opens or creates one
- the journal sits on top of the notes sidebar: days below each other
(today first, older ones load while scrolling), a calendar with month
and year picker follows the day in view and jumps to any day
- the header shares the day in view; journal notes stay out of the folder
tree; can be switched off per device under Darstellung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The custom webhook could be entered but never switched on since the
notification matrix replaced the old alarm channels. It is now a third
column next to e-mail and Discord for every event and the daily summary;
bundles go out as JSON (event "digest").
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- GET /link-preview?url= fetches the page on the server (https only,
SSRF-guarded like webhooks), reads Open Graph/Twitter tags, title,
description and icon from the head, loads picture and icon (no SVG) and
keeps them in link_previews (migration 6) for 7 days; readers' browsers
never contact the page. Off in the demo; 300 fetches per address in
15 minutes.
- Compact card above the bullet (icon, site, title, one line, small
picture); the duplicate link badge is left out.
- ✕ turns the address into [title](url), so hiding syncs with the note;
"Link-Vorschauen anzeigen" under appearance switches all off per device.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Backup ZIP (download and automatic per-user server backups) carries the
files of the user's own notes as media/<id><ext>; restoring creates
them with new IDs and rewrites the blocks.
- Markdown archive puts them under attachments/ and embeds them relative
to each note (); re-importing turns them
back into image/audio blocks.
- Obsidian import takes images and audio a note embeds on its own
(![[file.png]], ); unused or invalid files appear as
skipped in the preview instead of vanishing.
- Format detection and file paths moved into storage for this.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Demo: senders for mail, Discord and webhooks refuse, no alarm ticker;
test alarm, SMTP test, server settings, backups, account and session
changes of the shared demo accounts answer 403; the session list only
shows the own device. The UI shows the notices and disables the controls.
- SMTP password is never sent back (smtpPassSet), empty keeps it.
- ?token= on webhook ingest accepts only API keys.
- Request bodies capped at 2 MB (sync 8 MB, imports 101 MB).
- Deleting an account removes its server backups.
- Backup downloads, exports and import uploads get 30 minutes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Every login is a session (device, IP, last use); the token's jti is its ID.
Sessions end on logout, per device from the profile, or after 30 idle days.
- Tokens older than a day are renewed via the X-Session-Token header.
- Changing password or login e-mail needs the current password; a new
password logs out all other devices and mails the old address.
- Demo reset keeps the demo visitors' sessions.
- revoked_tokens is replaced by sessions (migration 4); everyone is logged
out once after the upgrade.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Admin settings: switch, time, retention, list with download and a
"Jetzt sichern" button. Account settings: own server backups with
download and restore (replace or add, for chosen sections, replace needs
a second tap). The MindSift import gets the same section picker.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
eslint.config.js with the recommended JS/TypeScript rules and the React
hooks rules; npm run lint runs ESLint and is part of the image build.
Errors fail the build, the 24 exhaustive-deps findings stay warnings.
It found two real bugs: TaskDetailModal and ManageColumnsModal called
their hooks after 'if (!isOpen) return null', so the hook count changed
whenever the dialog opened or closed. Both are now a thin wrapper plus a
content component. Also removes unused imports and dead code (old task
list share handlers, an unused realtime status, an unused rollup).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keys get scopes when created (webhook:triage, webhook:task,
webhook:list; default triage, old keys become triage). The webhook
ingest learns target task (optional task list) and list_item (needs a
list the owner may write to); /inbox checks the scope of its target as
well; a missing scope answers 403. Keys can no longer open live streams,
which carried all of the owner's events.
The visible key UI lived in the account settings while EcosystemView
was never rendered; it is replaced by ApiKeysPanel in the settings with
scope chips, scope badges per key and a simulator for all three
targets. Examples send the key as X-API-Key header, not in the URL.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
auth.ValidatePassword checks every way a password is set: setup,
registration, profile, admin create and reset, reset by mail. Same rule
in the browser before sending (lib/password.ts), with our own German
message instead of the browser popup. Existing shorter passwords still
log in. Profile and admin reset no longer trim the password, which made
passwords with surrounding spaces unusable for login.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Danger zone in settings: delete all own data or the account, both with
password confirmation; the last server admin cannot delete the account
- DELETE /user/data and /user/account; PurgeUserData removes everything a
user owns in one transaction (others' tasks in shared lists stay theirs),
also used by admin user deletion
- MindSift import: 'Hinzufügen' or 'Wiederherstellen' (mode=restore, wipes
own data only after the file is fully validated, confirm checkbox)
- API key name field and button 44 px on phones (flex-1 collapsed them)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GET /export?format=zip streams the JSON backup compressed (plain JSON stays
the API default). The MindSift import recognises the backup ZIP next to the
plain JSON and the Markdown archive.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Two separate paths: POST /import/mindsift (JSON backup or the Markdown
archive) and POST /import/obsidian (vault ZIP into a folder named after it)
- Everything is planned and validated first; ?preview=1 returns what would
be created and what is skipped (with reason), nothing is written
- MindSift data round-trips: folders, note structure, task lists with
subtasks/due dates/priorities/notes, lists with quantity/category/done,
triage thoughts from the JSON backup
- Markdown to outliner: nested lists, heading sections, callouts, code,
paragraphs; front matter tags become hashtags; .obsidian/attachments skipped
- Limits against zip bombs and path tricks (100 MB upload, 10 MB per note,
500 MB unpacked, 20k files, no .. escapes)
- Settings: two import cards with drag & drop, preview, confirm, result;
touch-sized buttons; mobile download/upload verified
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- GET /export/markdown streams the workspace as ZIP (no temp files):
notes as .md with YAML front matter in the user's folder structure
(shared notes and mounted folders included, empty folders kept)
- Clean Markdown: top-level headings/dividers/callouts/code as real blocks
(their children move up a level), lists with tabs, todos as - [ ]
- Aufgaben/<list>.md in Obsidian Tasks format (due date, priority,
subtasks, notes), Listen/<list>.md for shopping and other lists
- Safe, unique file names; download button in settings (mobile-safe)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- LEGAL_IMPRINT_/LEGAL_PRIVACY_ URL and Markdown (inline or *_FILE);
only http(s) URLs accepted
- /auth/status exposes legal info; public GET /legal/{imprint|privacy}
- Links on login/setup screen and in the settings footer: URL opens a new
tab, Markdown a reading modal; hidden when nothing is configured
- "Über MindSift" modal (version, license, repository) in settings and help
- Docs and compose/env examples
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Theme manager in settings: upload a .css file or paste CSS, template
download/copy/insert, edit and delete; custom themes show up in the
gallery and the quick switchers
- Themes are injected live as <style id="mindsift-custom-theme">; the
active one is cached so it applies on boot without flashing
- Backend: user_themes table and GET/POST /themes, DELETE /themes/{id}
(per user, max 200 KB)
- Docs: theming, REST, database
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>