Track session metadata (createdAt, userAgent, ip, lastUsedAt). Add API
for listing and revoking sessions. Settings page shows active sessions
with "Revoke" per session and "Log out everywhere else" option.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add PasswordStrengthMeter component showing visual bar and feedback.
Integrated in setup, settings change-password, and admin create-user forms.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5 failed attempts per IP triggers 15-minute lockout. Uses loginAttempts
table added in Phase 1. Returns 429 with Retry-After header.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update unit test helpers with full multi-user schema, fix auth tests to
include email field, and improve e2e tests with specific card targeting
and force clicks for hover-revealed buttons.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix session expiry check (seconds vs milliseconds mismatch in raw SQL),
conditionally render app chrome only for authenticated users, use full
page reload after login/setup for proper session propagation, remove
HTML minlength to allow JS validation, fix store to remove notes on
trash/archive, and make auth tests race-condition safe.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move migration logic (ALTER TABLE) before CREATE INDEX statements so
that user_id columns exist on old schemas before indexes reference them.
Disable foreign keys during schema setup to avoid constraint issues.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update e2e fixtures to use email+password for setup and login.
Update auth tests to fill email field. Add multi-user test for
admin creating a new user via API.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each user gets their own IDB database (keepnotes-{userId}), preventing
data leaks between users on the same device. Add initDb(userId) called
on mount and destroyDb() for logout cleanup.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- GET/POST /api/admin/users — list and create users (admin only)
- PATCH/DELETE /api/admin/users/[id] — update role/reset password, delete user
- PUT /api/auth/password — change own password
All admin routes guarded by requireAdmin().
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add layout.server.ts to pass event.locals.user to the client.
Header now shows user avatar initial with dropdown menu
(Settings link, Log out button).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add getUserId/requireAdmin helpers in api-utils.ts. All notes, tags,
search, sync, and attachment routes now filter by userId to ensure
complete data isolation between users. Sync server accepts userId
parameter for push/pull operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Login page now requires email + password. Setup page adds email and
optional display name fields. API endpoints updated to pass email
to verifyPassword/setupUser and explicit userId to createSession.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
validateSession now returns user data. Middleware sets event.locals.user
on every authenticated request. Add /api/auth/oauth to public paths.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Define App.Locals.user interface for session user data.
Add User type to shared types (mirrors DB columns minus passwordHash).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add email, displayName, role, authProvider, providerId to users table.
Add userId foreign key to notes, tags, attachments, syncLog tables.
Add loginAttempts table for rate limiting. Include migration logic
to detect old single-user schema and backfill existing data.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
loadNotes() crashed entirely if IndexedDB was unavailable because
getAllNotes() was called outside try/catch. Non-OK API responses
(401, 500) were silently ignored across loadNotes, createNote, and
sync operations — users saw empty data with no feedback.
Changes:
- Wrap all IDB calls in try/catch so the app works without IndexedDB
- Show toast on non-OK API responses in loadNotes and createNote
- Redirect to /login on 401 responses
- Make sync pull/push resilient to IDB unavailability
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DBs created before the image upload feature had no thumbnail_path column
in the attachments table. Since CREATE TABLE IF NOT EXISTS is a no-op for
existing tables, the column was never added, causing silent insert failures.
Add idempotent ALTER TABLE migration for thumbnail_path and surface upload
errors via toast notifications instead of swallowing them silently.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Images are hidden from card thumbnails by default. Users explicitly
feature images via a star toggle in the upload panel, and only featured
images appear in the card header strip.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Clicking a thumbnail in the editor, closed-panel view, or note card
opens a full-screen overlay with the full-size image. Closes on Escape,
background click, or X button. Escape is scoped so it won't close the
editor underneath.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of disabling the image button for unsaved notes, clicking it
now auto-saves the note first (with title "Untitled" if empty), then
opens the upload panel. This removes friction from the upload flow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use static test-image.png fixture instead of dynamic beforeAll creation
- Add thumbnail_path column to auto-create SQL in db/index.ts
- Hover on thumbnail before clicking remove button (group-hover:block CSS)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Swap Checklists feature card for Image Attachments with photo SVG icon.
Mention checklists in the Rich Editor card description instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Covers: upload → thumbnail in editor, persistence across close/reopen,
thumbnail on NoteCard, image removal, disabled toggle for unsaved notes.
Uses programmatically generated 1x1 PNG for test uploads.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Attachment images are immutable (UUID-based), so CacheFirst is ideal.
Previously-viewed images remain available offline even after blob URLs
expire. Rule placed before general NetworkFirst API rule to match first.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Bump IDB version to 2, add pendingAttachments object store with noteId index
- Add CRUD helpers: addPendingAttachment, getPendingAttachments, removePendingAttachment
- ImageUpload stores blobs in IDB when offline, displays via blob URLs
- Show pending sync indicator (RefreshCw icon) on not-yet-uploaded images
- Add pushPendingAttachments to sync client, runs after note push
- Pending attachments auto-upload on reconnect via existing online event listener
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Import ImageUpload into NoteEditor with attachment state management
- Add $effect to fetch attachments for existing notes loaded from IDB
- Add upload/remove handlers and image toggle button in toolbar
- Show ImageUpload panel between content and formatting toolbar
- Add full-bleed thumbnail strip at top of NoteCard (up to 3 images)
- Use &thumb=1 URL for card previews with lazy loading
- Show +N badge when more than 3 attachments
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add fetchAttachmentsForNotes() batch helper mirroring fetchTagsForNotes pattern
- Include attachments in all note API responses (list, single, sync)
- Fix ImageUpload.svelte URL bug (path-based → query param)
- Add client-side image optimization (resize, compress, WebP conversion)
- Add thumbnailPath column to attachments schema with migration
- Update saveAttachment/deleteAttachment for thumbnail file handling
- Update attachment API: accept thumbnail in POST, serve via &thumb=1 in GET
- Add Cache-Control immutable header for served attachments
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Upload both playwright-report/ and test-results/ (screenshots, traces)
on every run, not just failures.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Apply the same max-md:opacity-100 pattern from NoteCard to Checklist
drag handles and remove buttons, making them visible on touch devices.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests were clicking the done toggle expecting to expand it, but since
fed0fc1 changed doneExpanded to true by default, the click was
collapsing it instead — causing visibility assertions to fail.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove `needs` dependencies from e2e-tests and docker-build jobs.
They don't depend on lint/unit outputs — failures are visible from
their own jobs. Saves ~22s off the critical path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On touch devices, hover states don't work, so the pin/archive/delete
buttons were invisible. Now they're always visible on screens below the
md breakpoint and only hover-toggled on desktop.
https://claude.ai/code/session_013DdAk1yj6r3VF6Ze4ycidp