Fix Spotify invalid_client and Tidal redirect URI mismatch on auth
- Duplicate `spotify` key in saveSettings() object literal caused second definition (embed_tags/tags) to silently overwrite the first (client_id/client_secret/redirect_uri), destroying credentials on every save. Merged into single key. - authenticateSpotify() and authenticateTidal() now await saveSettings() before opening auth window, ensuring credentials are persisted. - Tidal auth now dynamically sets redirect_uri from request host for LAN/Docker users and stores it in tidal_oauth_state so the callback token exchange uses the same URI. Fixes #191
This commit is contained in:
parent
9a6ee0e229
commit
0a3cca4f1f
2 changed files with 24 additions and 11 deletions
|
|
@ -5858,8 +5858,19 @@ def auth_tidal():
|
|||
tidal_oauth_state["code_verifier"] = temp_tidal_client.code_verifier
|
||||
tidal_oauth_state["code_challenge"] = temp_tidal_client.code_challenge
|
||||
|
||||
# Dynamically set redirect_uri based on how the user is accessing the app
|
||||
request_host = request.host.split(':')[0]
|
||||
if request_host not in ('127.0.0.1', 'localhost'):
|
||||
dynamic_redirect = f"http://{request_host}:8889/tidal/callback"
|
||||
temp_tidal_client.redirect_uri = dynamic_redirect
|
||||
print(f"🔗 Tidal redirect_uri updated for remote access: {dynamic_redirect}")
|
||||
|
||||
# Store PKCE + redirect_uri for callback to use the same values
|
||||
with tidal_oauth_lock:
|
||||
tidal_oauth_state["redirect_uri"] = temp_tidal_client.redirect_uri
|
||||
|
||||
print(f"🔐 Stored PKCE - verifier: {temp_tidal_client.code_verifier[:20]}... challenge: {temp_tidal_client.code_challenge[:20]}...")
|
||||
|
||||
|
||||
# Create OAuth URL
|
||||
import urllib.parse
|
||||
params = {
|
||||
|
|
@ -6083,10 +6094,12 @@ def tidal_callback():
|
|||
# Create a temporary client for the token exchange
|
||||
temp_tidal_client = TidalClient()
|
||||
|
||||
# Restore PKCE values from the auth request (matches HTTPServer handler logic)
|
||||
# Restore PKCE values and redirect_uri from the auth request
|
||||
with tidal_oauth_lock:
|
||||
temp_tidal_client.code_verifier = tidal_oauth_state["code_verifier"]
|
||||
temp_tidal_client.code_challenge = tidal_oauth_state["code_challenge"]
|
||||
if "redirect_uri" in tidal_oauth_state:
|
||||
temp_tidal_client.redirect_uri = tidal_oauth_state["redirect_uri"]
|
||||
|
||||
success = temp_tidal_client.fetch_token_from_code(auth_code)
|
||||
|
||||
|
|
|
|||
|
|
@ -5708,7 +5708,9 @@ async function saveSettings(quiet = false) {
|
|||
spotify: {
|
||||
client_id: document.getElementById('spotify-client-id').value,
|
||||
client_secret: document.getElementById('spotify-client-secret').value,
|
||||
redirect_uri: document.getElementById('spotify-redirect-uri').value
|
||||
redirect_uri: document.getElementById('spotify-redirect-uri').value,
|
||||
embed_tags: document.getElementById('embed-spotify').checked,
|
||||
tags: _collectServiceTags('spotify')
|
||||
},
|
||||
tidal: {
|
||||
client_id: document.getElementById('tidal-client-id').value,
|
||||
|
|
@ -5795,10 +5797,6 @@ async function saveSettings(quiet = false) {
|
|||
genre_merge: _getTagConfig('metadata_enhancement.tags.genre_merge')
|
||||
}
|
||||
},
|
||||
spotify: {
|
||||
embed_tags: document.getElementById('embed-spotify').checked,
|
||||
tags: _collectServiceTags('spotify')
|
||||
},
|
||||
musicbrainz: {
|
||||
embed_tags: document.getElementById('embed-musicbrainz').checked,
|
||||
tags: _collectServiceTags('musicbrainz')
|
||||
|
|
@ -6238,7 +6236,9 @@ function updateStatusDisplays() {
|
|||
|
||||
async function authenticateSpotify() {
|
||||
try {
|
||||
showLoadingOverlay('Starting Spotify authentication...');
|
||||
showLoadingOverlay('Saving credentials and starting Spotify authentication...');
|
||||
// Save settings first to ensure client_id/client_secret are persisted
|
||||
await saveSettings();
|
||||
showToast('Spotify authentication started', 'success');
|
||||
window.open('/auth/spotify', '_blank');
|
||||
} catch (error) {
|
||||
|
|
@ -6387,10 +6387,10 @@ function formatRateLimitDuration(seconds) {
|
|||
|
||||
async function authenticateTidal() {
|
||||
try {
|
||||
showLoadingOverlay('Starting Tidal authentication...');
|
||||
// This would trigger the OAuth flow
|
||||
showLoadingOverlay('Saving credentials and starting Tidal authentication...');
|
||||
// Save settings first to ensure credentials are persisted
|
||||
await saveSettings();
|
||||
showToast('Tidal authentication started', 'success');
|
||||
// In a real implementation, this would open the OAuth URL
|
||||
window.open('/auth/tidal', '_blank');
|
||||
} catch (error) {
|
||||
console.error('Error authenticating Tidal:', error);
|
||||
|
|
|
|||
Loading…
Reference in a new issue