feat(lastfm): improve auth flow with embedded credentials support
- Add support for build-time credentials via LASTFM_API_KEY/LASTFM_API_SECRET env vars - Add lastfm_has_embedded_credentials command to check for embedded keys - Add lastfm_open_auth_url command to open browser via native opener - Simplify UI flow: if embedded credentials exist, just click Connect - Add cancel button during authorization flow - Clean up UI when waiting for user to authorize in browser
This commit is contained in:
1 parent
480594c03c
commit
19bad7200b
5 files changed
+112
-49
No files matched your search
@@ -55,6 +55,9 @@ souvlaki = "0.7"
|
||||
# Desktop notifications
|
||||
notify-rust = "4"
|
||||
|
||||
# URL opening
|
||||
open = "5"
|
||||
|
||||
# Storage
|
||||
# sled = "0.34"
|
||||
|
||||
|
||||
@@ -2,16 +2,28 @@
|
||||
|
||||
use tauri::State;
|
||||
|
||||
use crate::lastfm::LastFmSession;
|
||||
use crate::lastfm::{LastFmClient, LastFmSession};
|
||||
use crate::AppState;
|
||||
|
||||
/// Check if Last.fm has API credentials configured
|
||||
/// Check if Last.fm has embedded (build-time) credentials
|
||||
#[tauri::command]
|
||||
pub fn lastfm_has_embedded_credentials() -> bool {
|
||||
LastFmClient::has_embedded_credentials()
|
||||
}
|
||||
|
||||
/// Check if Last.fm has API credentials configured (embedded or user-provided)
|
||||
#[tauri::command]
|
||||
pub async fn lastfm_has_credentials(state: State<'_, AppState>) -> Result<bool, String> {
|
||||
let client = state.lastfm.lock().await;
|
||||
Ok(client.has_credentials())
|
||||
}
|
||||
|
||||
/// Open a URL in the default browser
|
||||
#[tauri::command]
|
||||
pub async fn lastfm_open_auth_url(url: String) -> Result<(), String> {
|
||||
open::that(&url).map_err(|e| format!("Failed to open browser: {}", e))
|
||||
}
|
||||
|
||||
/// Set Last.fm API credentials
|
||||
#[tauri::command]
|
||||
pub async fn lastfm_set_credentials(
|
||||
|
||||
@@ -9,10 +9,11 @@ use std::collections::BTreeMap;
|
||||
|
||||
const LASTFM_API_URL: &str = "https://ws.audioscrobbler.com/2.0/";
|
||||
|
||||
// Last.fm API credentials - users need to create their own app at https://www.last.fm/api/account/create
|
||||
// For now using placeholder - in production this should be configurable or use OAuth
|
||||
const API_KEY: &str = ""; // User must set this
|
||||
const API_SECRET: &str = ""; // User must set this
|
||||
// Last.fm API credentials
|
||||
// Set via environment variables at build time, or users can enter their own
|
||||
// To set: LASTFM_API_KEY=xxx LASTFM_API_SECRET=yyy cargo build
|
||||
const DEFAULT_API_KEY: Option<&str> = option_env!("LASTFM_API_KEY");
|
||||
const DEFAULT_API_SECRET: Option<&str> = option_env!("LASTFM_API_SECRET");
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LastFmSession {
|
||||
@@ -48,7 +49,17 @@ pub struct LastFmClient {
|
||||
|
||||
impl Default for LastFmClient {
|
||||
fn default() -> Self {
|
||||
Self::new(API_KEY.to_string(), API_SECRET.to_string())
|
||||
Self::new(
|
||||
DEFAULT_API_KEY.unwrap_or("").to_string(),
|
||||
DEFAULT_API_SECRET.unwrap_or("").to_string(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl LastFmClient {
|
||||
/// Check if embedded (build-time) credentials are available
|
||||
pub fn has_embedded_credentials() -> bool {
|
||||
DEFAULT_API_KEY.is_some() && DEFAULT_API_SECRET.is_some()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -141,10 +141,12 @@ pub fn run() {
|
||||
commands::get_cache_stats,
|
||||
commands::clear_cache,
|
||||
// Last.fm commands
|
||||
commands::lastfm_has_embedded_credentials,
|
||||
commands::lastfm_has_credentials,
|
||||
commands::lastfm_set_credentials,
|
||||
commands::lastfm_is_authenticated,
|
||||
commands::lastfm_get_auth_url,
|
||||
commands::lastfm_open_auth_url,
|
||||
commands::lastfm_authenticate,
|
||||
commands::lastfm_set_session,
|
||||
commands::lastfm_disconnect,
|
||||
|
||||
Reference in new issue
Block a user