Commit Graph
15 Commits
Author SHA1 Message Date
saopig1andClaude Opus 4.8 694ff77712 docs: guest-mode (login-less WebUI access) design spec (#83)
Brainstorm-approved design for an optional, default-off guest mode:
- guest = anonymous, config-driven principal (no account)
- per-ability admin toggles (add-to-end default on; play-next/play-now/
  skip/transport/remove-clear/play-mode opt-in) + per-bot guest scope
- unified authorize() gate; settings always locked for guests;
  non-destructive guest "play now"

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 23:20:49 +08:00
saopig1andClaude Opus 4.8 3a34c01abb fix(auto-pause): auto-resume on a listener's return via clientEnter event
Follow-up to the auto-pause fix: resume never fired when someone came back.

Root cause (verified live against a TS3 server): the full-client library's
command/response channel is dead whenever >=2 clients are connected anywhere on
the server — clientlist, channellist and channelclientlist ALL time out
(confirmed even with the two clients in different channels). So the moment a
listener returns is exactly the moment occupancy can no longer be queried, and
the query-based refreshOccupancy() can never observe the return -> no resume.
Event channelID is also unusable (library reads notify `cid` but enter-view
carries `ctid`, so it's always 0), so per-channel membership can't be derived
from events either.

Fix (minimal, asymmetric): keep PAUSE on the authoritative clientlist path
(reliable precisely because it only succeeds when the bot is alone on the
server — the only state pause should fire), and arm RESUME directly from the
clientEnter push event. Because the bot only auto-pauses while alone, the sole
way occupancy can return while autoPaused is set is a fresh connection, which
arrives reliably as clientEnter. New pure predicate shouldResumeOnReturn() +
_resumeIfReturning() resume iff autoPaused && paused; the resume branch routes
through handleOccupancy(1) and NEVER pauses (userCount>0), so a spurious enter
can only harmlessly resume. The bot's own enter at connect is a no-op
(autoPaused is already false).

This deliberately does NOT adopt a full event-tracked peer set: events don't
reliably seed clients already present when the bot joins, so a count-from-events
==0 would reintroduce the false-pause bug we just fixed, and reconcile can't
heal it (clientlist only works when alone). Pause must trust only the
authoritative query; resume can trust the event.

Net semantics: pause when the server is empty (bot alone), resume when someone
connects. Channel granularity is impossible with this library. UI copy updated
to say "服务器" instead of "频道", and the Settings toggle default corrected to
false to match the backend default. cmdVote intentionally left as-is.

Verified live: auto-paused bot + a real client connecting -> resume fires with
no clientlist call in the path; bot's own enter and not-auto-paused enters do
not resume. 311 unit tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 23:11:43 +08:00
saopig1 bea2f92508 Merge PR #80: feat(perm) fine-grained account permissions
Conflict resolution + cross-PR integration:
- player.ts: kept #88's POST /:botId/fm route AND gated it with
  requirePermission('player.control') so the new control endpoint honors #80's
  permission model (it was added without gating).
- bot.ts: kept #81's relocated /settings routes (the relocation fixes the GET
  /settings shadow bug) and dropped #80's now-duplicate bottom copy; gated
  POST /settings with requirePermission('bot.manage').
- Navbar.vue: composed #82's dedicated-link scope with #80's permission filter —
  displayedBots is now the INTERSECTION (scope ∩ controllable allow-list).
- database.ts: kept BOTH new table sets (#87 favorite_playlists + #80
  user_permissions/user_bot_access).
- bot.test.ts: updated to createRequireAuth(sessions, permissions) for #80's new
  two-arg signature.

#80 review fixes (credential exposure / IDOR, adversarially verified):
- GET /:id/config now requires bot.manage + bot access AND redacts ts6ApiKey +
  identity from the response (was readable by any authenticated member).
- GET /:id and GET /:id/avatar now require bot access (were ungated read oracles).
2026-06-16 15:05:57 +08:00
saopig1 c57cd35f09 Merge PR #81: feat(autopause) pause when bot channel empties 2026-06-16 14:43:54 +08:00
saopig1andClaude Opus 4.8 846fb2c28c docs(spec): dedicated-link bot scoping + refresh fix design (#79 items 2,4)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 15:06:09 +08:00
saopig1andClaude Opus 4.8 51c954993a docs(spec): auto-pause on empty channel design (#79 item 3)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 14:42:13 +08:00
saopig1 f0c979ce71 docs(spec): use 'capabilities' consistently for req.user field 2026-05-30 13:15:44 +08:00
saopig1andClaude Opus 4.8 f09a589940 docs(spec): fine-grained account permissions design (#79-E)
Capability flags (player.control/player.queue/bot.manage/platform.auth/quality) + per-member bot allow-list, layered under the existing member role; admin is super-user. Backend-enforced via requirePermission/requireBotAccess; existing members backfilled to full on upgrade, new members get a basic tier.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:44:24 +08:00
saopig1andClaude Opus 4.7 f7c16888e7 docs(spec): WebUI authentication design
Spec for adding username+password auth to the WebUI to close the
unauthenticated-API exposure (all /api/* and /ws currently open).

Design: SQLite users + sessions tables, bcryptjs, 7-day rolling
HTTP-only cookie sessions, first-run setup wizard, Origin/Referer
CSRF check, WebSocket upgrade gated on the same session cookie.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 13:07:51 +08:00
saopig1andClaude Opus 4.7 4407cd0c67 docs(spec): custom bot avatar + album search design
Spec for issue #51: custom avatar with idle/playback precedence rules,
and surfacing albums in search results + album detail playback. Two
features grouped in one spec; will land as two separate PRs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 19:49:53 +08:00
saopig1andClaude Opus 4.7 58bdfb94a9 docs: spec for history-aware prev + play-next insert
Two queue features:
- prev walks back through actual play history (50-entry stack), so
  random modes navigate predictably instead of falling back to the
  meaningless currentIndex-1 array walk.
- addNext inserts at currentIndex+1, exposed via new /play-next-song
  endpoint, !playnext command, and a third "下一首播放" button on
  SongCard. Insert path keeps playedIndices and history index refs
  valid by shifting entries > currentIndex.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 16:06:56 +08:00
saopig1andClaude Opus 4.7 e5ac3ad896 docs: spec for multi-source tabs on Home and Library
Design for adding NetEase / QQ source switcher tabs to recommend
playlists, daily songs, and user playlists on Home, plus user playlists
on Library. Tabs auto-hide when only one source is available; selection
persists per-section in localStorage.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 13:04:45 +08:00
fattiger 7eb8477dad docs: add design spec for FM bug fix, !artist command, and playlist fuzzy search 2026-04-27 16:55:35 +08:00
saopig1andClaude Opus 4.6 da5b34f5f4 feat(profile): auto-update bot avatar, nickname, and away status based on playing song
Add BotProfileManager that updates the bot's TeamSpeak presence when
songs change: album cover as avatar, song info in nickname, away status
toggled on stop/play. Each feature is independently configurable via
REST API and persisted to the database. Permission-safe — features that
fail due to insufficient server permissions are silently disabled until
reconnect. Description falls back to nickname display on TS3 (only
supported via TS6 HTTP Query).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 00:14:29 +08:00
saopig1andClaude Opus 4.6 9931d8b40d chore: Phase 1 complete — project scaffold, config, database, logger
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 00:21:55 +08:00