Commit Graph
16 Commits
Author SHA1 Message Date
TIANYAO ZHANGandClaude Opus 5.5 ac4a12d8bd feat(fm): let each web user link their own NetEase account for personal FM (#164)
With several people sharing one bot, personal FM always followed the one
account the bot was logged in with. Each signed-in (non-guest) web user
can now scan a QR code under Settings → 账户 to link their own NetEase
account; FM they start from the WebUI then comes from their account.

- user_music_cookies table (per user + platform, dropped with the user).
- NeteaseProvider.pollQrLogin returns the cookie without storing it, so
  a personal login can never replace the bot's shared account;
  checkQrCodeStatus is now built on it. withCookie gives a view bound to
  another account.
- /api/me/music/netease: status / qrcode / qrcode/status / unlink, acting
  only on req.user. The cookie never leaves the server.
- POST /api/player/:botId/fm uses the caller's linked account for
  NetEase. Songs still resolve through the shared provider when played.

TeamSpeak chat !fm keeps using the shared account: chat users are not
tied to web accounts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-27 22:02:31 +08:00
saopig1 c8dacebc45 Merge remote-tracking branch 'origin/main' into feat/issue-119-saved-playlists
# Conflicts:
#	src/data/config.ts
2026-07-17 11:09:04 +08:00
saopig1andClaude Fable 5 69a2e8c264 feat(#119): save/load queues + live-queue persistence + playKeepsQueue (backend)
Add three default-off capabilities that stop the play queue from being lost,
all gated behind admin/independent toggles so existing behavior is unchanged
until an operator opts in:

- Named save/load of queues (Feature 1): new saved_queues table (per-user +
  reserved __shared__ owner, capped at 50 queues / 1000 songs, JSON song blob
  that degrades to empty on corruption); /api/saved-queues router (list/save/
  load/delete with ownership 404s, inert 403 when disabled); chat commands
  !save / !load [-a] / !queues; BotInstance.loadSavedQueue (replace/append).
- Auto-restore live queue across restart (Feature 2): PlayQueue.snapshot/restore,
  queue_state table (one row per bot), a debounced snapshot writer driven off
  stateChange, and restore+resume on connect. Cancels the pending snapshot on
  disconnect so a stale write can't wipe the row a restart must restore.
- playKeepsQueue (Feature 3): BotInstance.playSingleSong funnels chat !play and
  the web /play-song route through one place; when enabled a single-song play
  inserts-after-current and jumps instead of clearing the queue.

Config gains savedQueuesEnabled + playKeepsQueue (both default false, strict-
coerced on load like spotify.enabled); the settings API round-trips them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 01:28:48 +08:00
saopig1andClaude Fable 5 fbd94c424b feat: persist volume, play mode and audio quality across restarts
Runtime playback settings were kept only in memory (AudioPlayer.volume,
PlayQueue.mode, each provider's quality field), so restarting the bot reset
them to defaults and users had to re-tune volume and quality every time (#125).

Persist and restore them via the repo's existing storage:
- Volume and play mode are per-bot, stored on new bot_instances columns
  (volume, play_mode) with a schema migration; restored when the instance is
  (re)built, written by cmdVol / cmdMode which every entry point (chat command,
  WebUI, REST) funnels through. Volume and mode are written independently so a
  transient !fm/!artist mode switch never overwrites the user's saved !mode.
- Per-provider audio quality is global (shared providers), stored in a new
  config.json `audioQuality` block; applied to the providers at startup and
  re-snapshotted on POST /api/music/quality.

Queue, current song, progress and FM/artist sessions stay ephemeral.

Adds tests for config sanitize/round-trip, DB player-settings + migration,
cmdVol/cmdMode persistence + construction-time restore, and quality persistence
through the REST endpoint. Documents the behavior in the README.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 00:09:47 +08:00
Fa1nttt cb66d77e9c feat: show requester names in play history 2026-07-04 22:32:21 +08:00
saopig1andClaude Opus 4.8 271504eec1 feat(db): seed reserved guest principal idempotently
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 11:30:12 +08:00
Dr1mH4X 4244695075 feat: Add channelId support to bot configuration and database 2026-06-23 02:37:13 +08:00
saopig1andClaude Opus 4.7 a73f797bcb feat(auth): two-role permission system (admin/member)
Adds an admin/member role to WebUI auth. /api/users and /api/audit
are now gated by a requireAdmin middleware; all other authenticated
endpoints accept both roles. Schema migration defaults all existing
users to admin to preserve access. POST /api/users defaults new users
to member; first-run setup always creates an admin. Adds PATCH
/api/users/:id/role with last-admin demotion and deletion guards.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 15:35:15 +08:00
saopig1andClaude Sonnet 4.6 6af0e97f51 feat(auth): user-management audit log (table + record sites + /api/audit endpoint)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 15:04:19 +08:00
saopig1andClaude Sonnet 4.6 8ea1a64c59 feat(db): add users and sessions tables for WebUI auth
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 13:27:12 +08:00
saopig1andClaude Sonnet 4.6 366edf7843 feat(db): custom_avatar_path column + accessors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 19:59:20 +08:00
saopig1andClaude Opus 4.7 652424b74c fix: post-merge type and test fixes
Library.vue: use Song type from store so SongCard's strict platform
union accepts the data (was platform: string, broke after merge tightened
SongCard prop type).

database.test.ts: switch toEqual -> toMatchObject so getBotInstances()
returning extra profile_* schema columns no longer fails the assertion.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 12:47:19 +08:00
saopig1andClaude Sonnet 4.6 d5d6abeb1e feat: implement server password login, YouTube source, and improved bot selector UI
- **TS server password** (#7/#9): add serverPassword field across database,
  manager, bot API, and Settings UI — allows joining password-protected servers
- **YouTube audio source** (#1/#10): new YouTubeProvider using yt-dlp binary;
  adds -y flag in chat commands, /api/music supports platform=youtube,
  YouTube badge in SongCard, yt-dlp-wrap npm dependency
- **Bot selector UI** (#14): selector always visible (not just when >1 bot),
  bigger button with border and play-state indicator; per-bot URL routing at
  /bot/:id with BotRedirect view; copy-link button in dropdown

Closes #1, #7, #9, #10, #14

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 11:58:07 +08:00
Claude 6184f38330 Fix 7 corner cases found in second review pass
Critical:
- Persist serverProtocol/ts6ApiKey in database schema so TS6 config
  survives restarts (added columns + manager save/load)

Medium:
- Clear udpErrorTimer on disconnect to prevent memory leak and stale
  log messages from firing after teardown
- Guard against double connect() by disconnecting old client first
- Add settled guard in TS6HttpQuery.request() to prevent double
  reject when both res error and req error fire
- Add res.on("error") handler to TS6HttpQuery response stream

Low:
- Cap probeTS3Query banner buffer at 256 bytes to prevent memory abuse
  from non-TS3 services sending large data on port 10011
- Remove unnecessary EventEmitter inheritance from TS6HttpQuery
- Update database test fixtures with new serverProtocol/ts6ApiKey fields

https://claude.ai/code/session_016WhH58avUD9xy2dgADJgTh
2026-04-03 13:38:49 +00:00
saopig1andClaude Opus 4.6 bc89c553b7 fix: address Phase 1 review — union types, auto playedAt, ESM imports, gitignore config.json
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 00:26:55 +08:00
saopig1andClaude Opus 4.6 8727605036 feat: add SQLite database module with play history and bot instances
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 00:21:07 +08:00