Replace the in-memory JSON-backed store with a SQLite option using
modernc.org/sqlite (pure Go, no CGo). Add user authentication with
bcrypt password hashing and random session tokens.
SQLite store:
- Schema covers nodes, exports, tokens, ordinals, users, sessions
- WAL mode and foreign keys enabled
- Set BETTERNAS_CONTROL_PLANE_DB_PATH to activate (falls back to
memory store when empty)
User auth:
- POST /api/v1/auth/register, login, logout, GET /me
- bcrypt (cost 10) for passwords, 32-byte hex session tokens
- Sessions stored in SQLite with configurable TTL
- Client endpoints accept session tokens or static client token
- CORS middleware via BETTERNAS_CORS_ORIGIN env var
New env vars: BETTERNAS_CONTROL_PLANE_DB_PATH, BETTERNAS_SESSION_TTL,
BETTERNAS_REGISTRATION_ENABLED, BETTERNAS_CORS_ORIGIN
24 tests pass including 7 SQLite store tests and 7 auth tests.
Builds clean with CGO_ENABLED=0.
macOS WebDAVFS truncates HTTP Basic Auth passwords at 255 bytes. The
mount credential password (base64 payload + HMAC signature) was 260
bytes because the full username token (32 random bytes / 43 base64url
chars) is embedded in the signed payload.
Reduce the username token from 32 bytes to 24 bytes (32 base64url
chars), bringing the total password to ~246 chars with margin for
longer node IDs and mount paths.
macOS Finder sends an unauthenticated OPTIONS request before attempting
auth. It needs to see the DAV: 1, 2 compliance header in the response
to know the server supports WebDAV. Without it, Finder shows "problem
connecting to the server" and never prompts for credentials.
OPTIONS is a safe discovery method that exposes no data, so it can be
served without auth.
Go's webdav.Handler returns 405 Method Not Allowed for GET on
collections (directories). macOS Finder sends GET to the WebDAV root
as part of its mount flow and refuses to connect when it gets 405.
Add a finderCompatible wrapper that intercepts GET/HEAD on directories
and returns a minimal 200 response, while passing all standard WebDAV
methods through to the underlying handler unchanged.
Add the first control-plane UI over the verified backend seam so exports,
issued DAV credentials, and Finder instructions can be exercised from the
running stack.
Split node enrollment from export sync and issue Finder-compatible DAV
credentials so the stack proves the real backend seam before any web UI
consumes it.
Protect the control-plane API with explicit bearer auth, add node-scoped
registration/heartbeat credentials, and make export mount paths an explicit
contract field so mount profiles stay correct across runtimes.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>