Repository navigation
v0.2.0
Added
- Export: every user can download all their notes as a ZIP of Markdown files with YAML front matter (compatible with Joplin's Markdown + front matter import), organized in notebook folders, with their attachments and working relative links (account menu > Export notes,
GET /api/export). - Security log: sign-ins, failed sign-ins, account locks, sign-outs, password and account changes, refused cross-origin requests and rate limit hits are logged under
Notes.Securitywith stable event ids. Notes__TrustedProxies: the addresses a reverse proxy may connect from (defaults to private networks).- Release workflow: multi-arch images on GHCR with signed build provenance, SBOM attestations and CycloneDX SBOMs attached to each GitHub release.
- CodeQL, OpenSSF Scorecard, dependency review, NuGet and npm audit and a container image scan in CI; Dependabot for all dependency ecosystems.
- Contributing guide and issue and pull request templates.
- Documentation: security policy, security guide, deployment guide, CRA compliance and the architecture documentation in arc42 form.
Changed
- Breaking: passwords need at least 12 characters (was 8) and at most 1024. Existing passwords keep working; the rule applies the next time a password is set.
- Passwords are hashed with 210,000 PBKDF2 iterations (was 100,000). Existing hashes are upgraded on the next sign-in.
- Sessions end at the latest 90 days after sign-in, even when in use (
Notes__SessionMaxAgeDays). - Breaking: invalid settings stop the start with a message naming them (an unknown
Notes__CookieSecurevalue, aNotes__PublicUrlthat isn't an absolute http(s) URL, limits below their minimum, unparsableNotes__TrustedProxies). Before, such values were silently replaced by defaults. docker-compose.ymlruns the app with a read-only filesystem, without Linux capabilities and withno-new-privileges. Base images are pinned by digest, GitHub Actions by commit, NuGet packages by lock file.
Security
- An account is locked for 15 minutes after 10 failed sign-ins, from any address (
Notes__LoginMaxFailures). - Forwarded headers are only accepted from trusted proxy addresses.
- New response headers:
Strict-Transport-Securityover HTTPS,Permissions-Policy,Cache-Control: no-storefor API responses; theServerheader is no longer sent. - Overlong passwords are refused before hashing.
- A password change or reset that fails to save no longer ends the user's sessions while keeping the old password: the new hash and the session cleanup are one transaction, and the security log entry is written only after it committed.
- Exports are logged as security event 1050 (who, from which address), since a full export is the first thing to look for after a stolen session.
Image: ghcr.io/kamineko/notes:0.2.0 (sha256:b49c4783a13da0e770c3dff56c16a5002f316b8544a3b9be4cf849423d1ad6f9, linux/amd64 and linux/arm64). Verify it with gh attestation verify oci://ghcr.io/kamineko/notes:0.2.0 --repo KamiNeko/notes. See CHANGELOG.md for upgrade notes and SECURITY.md for supported versions.
What's Changed
- feat: Notes, a standalone Markdown notes app with a .NET 10 backend by @KamiNeko in #1
- Security hardening, CRA alignment, export and arc42 documentation by @KamiNeko in #2
- chore: update undici to 8.12.3 by @KamiNeko in #38
- refactor: share the note lookup and the conflict check in NoteService by @KamiNeko in #26
- chore: require Node 24 for the client and drop __dirname from the Vite config by @KamiNeko in #30
- test: cover pruning of versions past the retention period by @KamiNeko in #32
- test: cover the users command line by @KamiNeko in #33
- test: cover ChangePasswordDialog and the trash's notebook list by @KamiNeko in #35
- docs: correct and complete the REST API reference by @KamiNeko in #36
- refactor: one helper restores trashed parent notebooks by @KamiNeko in #27
- fix: validate the settings on startup by @KamiNeko in #28
- docs: add CONTRIBUTING.md and issue and pull request templates by @KamiNeko in #37
- fix: save a new password and end sessions in one transaction by @KamiNeko in #29
- feat: log exports as a security event by @KamiNeko in #31
- chore: release 0.2.0 by @KamiNeko in #39
New Contributors
Full Changelog: https://github.com/KamiNeko/notes/commits/v0.2.0