4.1 KiB
4.1 KiB
Changelog
All notable changes to librenotes are recorded here. The format loosely follows Keep a Changelog, and the project follows Semantic Versioning.
[Unreleased]
0.1.0 — 2026-04-29
The initial public release: a fork of Notesium turned into a multi-tenant SaaS, plus the surrounding infrastructure.
Added
- Fork. Forked alonswartz/notesium
at
aff9f460c2d864112db7f0935b4168b107289d91, restructured into the standard Go layout (cmd/,internal/), renamed the module togit.librete.ch/public/librenotes, preserved the MIT license alongside librenotes copyright, documented the upstream remote and cherry-pick workflow. - User model + SQLite storage (
internal/storage). UUIDv4 IDs, email uniqueness, WAL mode, embedded migrations. - Magic-link authentication (
internal/auth). 32-byte cryptographically random tokens, SHA-256-hashed at rest, single-use, 15-minute expiry. HS256 JWT sessions with 24-hour lifetime,jwt.WithValidMethodsto rejectalg=none. PluggableMailerinterface withSMTPMailerand dev-friendlyLogMailer. DB-backed per-email rate limiting. - Per-tenant filesystem isolation (
internal/tenant). Each user gets a sandboxed directory; all reads and writes go throughos.Rootso path traversal and symlink escapes are rejected at the syscall layer. - Tenant-aware HTTP API (
internal/httpapi). JWT middleware, tenant context,/api/whoami,/api/notesCRUD with optimistic-locking conflict detection (?base=<unix>),/healthz. librenotes servecommand wires storage, auth, tenants, notes, and a static frontend into one binary. Configuration viaLIBRENOTES_*env vars or flags. Background goroutine purges expired magic tokens.- Frontend (
cmd/librenotes/web/public/): mobile-first landing page, login + verify pages, app shell with sync badge and conflict dialog. Vanilla JS, no build step. - JWT session client with sessionStorage + automatic
Authorization: Bearerinjection and 401-redirects-to-login. - Tenant-scoped localStorage wrapper so two users on the same browser have isolated UI state; cleared on logout.
- Offline cache in IndexedDB (
notes-cache.js) with dirty tracking and tombstones for deletes. - Background sync (
sync.js) — pushes dirty rows on reconnect, pulls remote changes, surfaces conflicts to the UI via custom events. - PWA support: manifest, service worker (cache-first shell, network-first API), 192/512/maskable icons, install prompt.
- Responsive CSS with explicit breakpoints from 320px to 2560px, including a 3-column ultrawide layout primitive.
- Pointer events on the resize handle so touch and pen work identically to mouse, including pointer capture for drag.
- Containerised deployment: multi-stage Dockerfile producing
a distroless
nonrootimage, dev + prod Compose stacks, in-binarylibrenotes healthcheckfor distroless HEALTHCHECK. - CI: Gitea Actions workflow runs
make lint,make build,make teston every push and PR. - Deploy workflow (gated on
DEPLOY_ENABLED=true) builds and pushes images, SSHes to the host, runscompose pull && up -d, polls/healthz. - Backup tooling (
scripts/): SQLite online snapshot + tar of notes, optional rclone off-site copy, retention pruning, weekly automated restore-test, systemd timer units. - Documentation: user guide, self-hosting, API reference, operations, contributing.
- Community infrastructure: bug-report and feature-request Gitea issue templates, PR template, Code of Conduct.
- First-run onboarding: welcome dialog + seeded sample note, dismissal persisted per tenant.
Notes
- The bundled notes engine (the original Notesium UI under
internal/notesium/web/app/) is not yet wired into the multi-tenant frontend. Phase 7 will replace or wrap it. - SMTP delivery has been exercised against the LogMailer only; real-provider integration is part of self-hosting validation.