Commit Graph

10 Commits

Author SHA1 Message Date
bvandeusen 97e0e88483 feat(server): scan library on startup by default + README first-run walkthrough
test-go / test (push) Successful in 37s
test-go / integration (push) Successful in 4m38s
Make a fresh install usable out of the box and document the first-run flow
for the public-facing repo.

- Default scan_on_startup to true (Default() + config.example.yaml, which is
  the live config baked into the image). Previously false, so a fresh stack
  came up with an empty library and no hint to scan. Scans are incremental
  (mtime skip), so the per-restart cost is just a directory walk. Re-point
  the env-override test to exercise the override against the new default.
- README: add a "First run" walkthrough (register -> scan -> integrations ->
  install Android app -> invite users), each grounded in a real route.
- Add docs/screenshots/ with six captures, referenced via width-constrained
  <img> wrapped in a link (shrink inline + click to open full size).
  API token and invite token were cropped/redacted out of the captures
  before commit so no live credential lands in the public history.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 11:35:22 -04:00
bvandeusen c3614c6333 fix(server): errcheck violations from UPnP slice
test-go / test (push) Successful in 29s
test-go / integration (push) Has been cancelled
golangci-lint flagged three errcheck:
- stream_token.go: fmt.Fprintf(mac, ...) - hash.Hash never errors
  per documented contract, but errcheck wants explicit discard.
  Discard via _, _ assignment with a WHY comment.
- config_test.go: os.Unsetenv calls in tests - discard the error
  via _ assignment. Test cleanup paths.

Reviewers flagged the Fprintf one during Task 1 quality review but
golangci-lint runs in a separate CI step that wasn't exercised on
the per-task pushes (cancelled by subsequent push concurrency).
2026-06-03 13:41:54 -04:00
bvandeusen e774097fd8 feat(server): POST /api/cast/stream-token + secret bootstrap (UPnP slice 2/6)
test-go / test (push) Failing after 15s
test-go / integration (push) Failing after 5m54s
Adds the client-facing endpoint that issues a signed stream URL for
the current track. Authenticated via the standard session cookie.
Returns {token, exp, url} where url is a fully-formed stream URL
the client passes verbatim to a UPnP / Sonos device's
AVTransport.SetAVTransportURI call.

expSeconds clamped to [60, 86400]; default 21600 (6h) - long enough
to play through any typical track without re-minting mid-playback.

MINSTREL_STREAM_SECRET is loaded from env var with a per-machine
fallback persisted at <Storage.DataDir>/stream_secret (auto-generated
on first boot via 64 random bytes, base64-url-encoded, 0600). The
file-based fallback is operator-machine-scoped runtime state, not a
user-facing setting - chosen over a DB column to avoid a migration
and keep the secret out of cross-instance restores. Operator can
override at any time via the env var; default path requires zero
config.

Tests cover happy-path token issuance + URL formatting, bad-UUID
rejection, unauthenticated rejection, the expSeconds clamp at all
boundaries, secret env override, auto-gen + file persistence at 0600,
second-boot reuse of the persisted file, and rejection of a malformed
env value.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-03 11:46:57 -04:00
bvandeusen c4cccea775 refactor(server): remove bootstrap admin path
The bootstrap-admin-from-env-vars flow was a holdover from before
self-registration could create the first admin. Now that handleRegister
+ CreateUserFirstAdminRace promotes the first user to register on an
empty users table (verified shipped in v2026.05.08.2 / #376), the
bootstrap path is just a second source of truth that confuses operators
(and leaves an "admin" account in the DB that nobody asked for).

Removes:
- internal/auth/bootstrap.go + its test
- The auth.Bootstrap call from cmd/minstrel/main.go
- AuthConfig + AdminBootstrapConfig structs from config
- MINSTREL_AUTH_ADMIN_USERNAME / _PASSWORD env reads + their test
- The auth: block from config.example.yaml
- Bootstrap-related comments in docker-compose.yml + README.md

The README quickstart now points operators at /register on first start
instead of "watch the logs for a one-time password."

Existing instances keep their bootstrap-admin row in the DB; operators
who want it gone can register a new admin via /register, promote them
in /admin/users, then delete the old bootstrap user (last-admin guard
will require the new admin to be promoted first). No migration needed.

Recovery story for forgotten admin passwords now hinges on Fable #321
(admin password reset CLI) — currently the only path back in if no
other admin exists.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 22:14:33 -04:00
bvandeusen ca82862346 chore(config): rename SMARTMUSIC_ env prefix to MINSTREL_; default admin user
The legacy SMARTMUSIC_ prefix dates from when the project was specced
as "smart-music" before being renamed to Minstrel. Hard cutover to
MINSTREL_* across config.go, tests, config.example.yaml, README, and
docker-compose. Also renames SMARTMUSIC_CONFIG in cmd/minstrel/main.go
which was missed in the original audit.

Also seeds Auth.AdminBootstrap.Username = "admin" in Default() so
MINSTREL_DATABASE_URL is the only env var required for a fresh prod
deployment — the bootstrap auto-generates a password and prints it
to stderr. Drops the now-redundant MINSTREL_AUTH_ADMIN_USERNAME=admin
line from the README quickstart and docker-compose.

M1 follow-up from the #363 final review: guards
MINSTREL_BRANDING_APP_NAME and _DESCRIPTION against empty-string
overrides — empty would have shipped <title></title> to share-preview
crawlers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 18:40:59 -04:00
bvandeusen cd50ffd77d feat(config/m7-363): branding config field + defaults 2026-05-03 17:14:59 -04:00
bvandeusen f8b0d78544 test(config): subsonic env override 2026-04-19 17:39:48 +00:00
bvandeusen 29d32e3097 M1/#293: cover LibraryConfig env + yaml 2026-04-19 15:15:29 +00:00
bvandeusen d7e04a757a M1/#292: test env overrides for admin bootstrap 2026-04-19 02:30:51 +00:00
bvandeusen a29d876ac4 test(config): cover defaults, YAML load, missing file, env overrides 2026-04-18 21:20:02 +00:00