Add generic short code authentication system (#3078)
* feat: add generic short code authentication system
Add a reusable short code authentication system that any provider can use
for QR code login, device pairing, or similar flows.
Changes:
- Add join_codes database table (schema v6)
- Add generate_join_code(user_id, provider_name, ...) method
- Add exchange_join_code() to convert codes to JWT tokens
- Add auth/code public API endpoint
- Add revoke_join_codes() for cleanup
- Update login.html to handle ?join= parameter
- Add provider_name parameter to JWT token encoding
Providers can implement short code auth flows like:
code, expires = await auth.generate_join_code(
user_id=my_user.user_id,
provider_name="my_provider",
expires_in_hours=24,
)
The provider_name is stored in the join code and passed to the JWT token,
allowing providers to identify their authenticated sessions.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: Revise db migration
* test: add comprehensive tests for join code authentication
Add tests covering the short code authentication system:
- generate_join_code: basic functionality, invalid user handling
- exchange_join_code: success, case-insensitivity, expired codes,
max_uses limits, unlimited uses, provider_name in JWT claims
- revoke_join_codes: per-user revocation, revoke all codes
- authenticate_with_join_code API: success and error cases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Update music_assistant/controllers/webserver/auth.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/helpers/resources/login.html
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/controllers/webserver/auth.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/controllers/webserver/auth.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix: Simplify join code schema
* chore: Update join code test
* fix: Fix revoke_join_codes() to use correct db count function
* fix: Simplify revoke_join_codes and add provider handling
* fix: Avoid useless rename
* fix: Handle rare collision edge case
* fix: Fix return type
* fix: Use named params
* fix: Rename prevents already defined error
* Add input validation to generate_join_code.
* Fix unhandled RunTimeError.
* Limit short codes to users with guest role only.
* Log security events.
* Rename endpoint and add endpoints to list and revoke codes.
* Make at least one parameter of revoke_join_codes required to prevent accidental deletion of all codes.
* Schedule cleanup of expired join codes once a day.
* Minor cleanup.
* Fixes for active source and current media with linked protocols
* Fix DSP not applying for AirPlay and Sendspin players (#3191)
* OpenSubsonic: Use server provided version tag if present (#3200)
* Fix use playerid for http profile
* ⬆️ Update music-assistant-frontend to 2.17.92 (#3203)
Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
* Expand PIN based auth in airplay 2 (#3165)
* add LG details
* Make pin based auth work in other devices
* remove reference to apple tv and macos in check
* remove unused constant and adjust airplay2 filter
* also apply pairing check to raop
* add unit test
* Revert MIN_SCHEMA_VERSION to maintain HA compatability.
* Add comments to schema version constants
* Fix some more issues with syncgroups
* Fix HEOS source switching back to Local Music after starting stream (#3206)
* Fix group mute for protocol-synced players (#3205)
* Handle HEAD requests on root route (#3204)
* Fix announcements typo
* Some small code quality changes to DLNA Provider
* Small simplification for GroupPlayer
* Fix Sonos S2 announcement 404 error on cloud queue context endpoint (#3208)
* Snapcast: Fixes for hard switching of group leaders (#3209)
* Gracefully skip files/folders with emoji names on SMB mounts (#3183)
* Add API to handle playback speed (#3198)
* Simplify can_group_with logic
* Airplay2-configurable-latency (#3210)
* Validate queue item ID in Sonos pause path (#3194)
* Add some additional guards to asyncprocess
* Add a bunch of extra error handling and logging for flow streams
* Properly cleanup stream buffers
* ⬆️ Update music-assistant-frontend to 2.17.93 (#3214)
Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
* Fix bluesound volume jumping back after volume_set.
* Speed-up core startup a bit
* More gracefully handle DLNA errors
* Lock set_members to avoid concurrent actions
* Fix issue with subprocess pips closing
* Fix ungroup command
* Add note in docstring
* Auto ungroup when trying to form syncgroup with already synced player
* Fix accessing player.state.synced_to
* Fix playback speed handling on queue item and not on queue
* Fix for _cleanup_player_memberships
* Fix race condition with enqueue_next_media on SyncGroup
* Fix some edge cases with AirPlay DACP commands
* Fix set_members with lock
* Fix player not available in HA at startup
* Fix fully_played should return boolean
* Auto translate commands directed at protocol player id to visible parent
* Some minor tweaks to handling prevent-playback of airplay
* Speedup core controller startup
* Pre-compile Python bytecode in Dockerimage for faster startup
* Speedup is_hass_supervisor check
* Fix _cleanup_player_memberships and _handle_set_members
* Fix player config not fully persisting
* ⬆️ Update music-assistant-frontend to 2.17.94 (#3218)
Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
* Bandcamp: validate login on init when credentials are configured (#3215)
Co-authored-by: David Bishop <git@gnuconsulting.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix bluesound volume jumping back after volume_set.
* Use ImageType.THUMB for Bandcamp artwork images (#3212)
Bandcamp artwork is square, not landscape. All other music providers
in the codebase use THUMB for standard album and artist art.
Co-authored-by: David Bishop <git@gnuconsulting.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix inverted track_number condition in Bandcamp converter (#3211)
The condition checked output.track_number instead of track.track_number,
meaning track numbers from the API were only applied when the output
already had a non-None default.
Co-authored-by: David Bishop <git@gnuconsulting.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Clear internal HEOS queue before playing (#3219)
* Update Alexa player provider (#3167)
* Update Alexa player provider
* Remove redundant try catch
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Address PR comments
* Remove ActionUnavailble catches
* Remove extra catch alls and add _on_player_media_updated
* Remove catch all
* Bump AlexaPy
* Fix _upload_metadata when media is not available
---------
Co-authored-by: Sameer Alam <alams154@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Fix race condition in player register flow wrt config
* Fix select output protocol already in play_index to avoid race on flow mode
* Fail job on test failures
* Fix Radioparadise image URL (#3220)
The change to the documentation repo moved the images
* Fix flow mode determination
* Fix player tests
* Add genre icons and SVG handling to imageproxy (#3223)
* Add genre icons and SVG handling to imageproxy
* Cleanup
* ⬆️ Update music-assistant-frontend to 2.17.95 (#3222)
Co-authored-by: stvncode <25082266+stvncode@users.noreply.github.com>
Co-authored-by: Marvin Schenkel <marvinschenkel@gmail.com>
* Fix static members of sync group
* Fix last small issues with syncgroup
* Fix issue with clearing output protocol during track changes
* Use mass.call_later.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Marvin Schenkel <marvinschenkel@gmail.com>
Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
Co-authored-by: Maxim Raznatovski <nda.mr43@gmail.com>
Co-authored-by: Eric Munson <eric@munsonfam.org>
Co-authored-by: music-assistant-machine <141749843+music-assistant-machine@users.noreply.github.com>
Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
Co-authored-by: hmonteiro <1819451+hmonteiro@users.noreply.github.com>
Co-authored-by: Tom Matheussen <13683094+Tommatheussen@users.noreply.github.com>
Co-authored-by: scyto <alex@alexbal.com>
Co-authored-by: David Bishop <teancom@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Mischa Siekmann <45062894+gnumpi@users.noreply.github.com>
Co-authored-by: OzGav <gavnosp@hotmail.com>
Co-authored-by: Andy Kelk <andy@andykelk.net>
Co-authored-by: Brad Keifer <15224368+bradkeifer@users.noreply.github.com>
Co-authored-by: Bob Butler <bob@robertjbutler.com>
Co-authored-by: David Bishop <git@gnuconsulting.com>
Co-authored-by: Sameer Alam <31905246+alams154@users.noreply.github.com>
Co-authored-by: Sameer Alam <alams154@users.noreply.github.com>
Co-authored-by: stvncode <25082266+stvncode@users.noreply.github.com>