fix(backend): hydrate session token without triggering keychain prompts

This fixes a severe issue where 'hydrate_pairing_token' was hardcoded to fetch from the keychain on startup and via the 'hydrate_extension_pairing_token' command. This caused multiple macOS keychain prompts to appear back-to-back before the app even loaded. We now correctly check the user's 'keychainAccessGranted' preference from the DB payload and skip keychain operations entirely if they haven't explicitly granted access yet.
This commit is contained in:
NimBold
2026-06-24 22:00:12 +03:30
parent 7213606182
commit e1f62c949d
2 changed files with 19 additions and 4 deletions
+14
View File
@@ -549,6 +549,20 @@ pub fn load_settings(connection: &Connection) -> Result<Option<String>, String>
.map_err(|error| format!("failed to load settings: {error}"))
}
pub fn is_keychain_access_granted(connection: &Connection) -> Result<bool, String> {
let Some(settings) = load_settings(connection)? else {
return Ok(false);
};
let document: Value = serde_json::from_str(&settings)
.map_err(|error| format!("failed to decode settings: {error}"))?;
let granted = document
.get("state")
.and_then(|s| s.get("keychainAccessGranted"))
.and_then(|v| v.as_bool())
.unwrap_or(false);
Ok(granted)
}
pub fn save_settings(connection: &Connection, data: &str) -> Result<(), String> {
connection
.execute(
+5 -4
View File
@@ -3069,7 +3069,8 @@ fn hydrate_extension_pairing_token(
app_state: tauri::State<'_, AppState>,
) -> Result<PairingTokenHydration, String> {
let mut connection = database.lock()?;
match crate::db::hydrate_pairing_token(&mut connection, false) {
let skip_keychain = !crate::db::is_keychain_access_granted(&connection).unwrap_or(false);
match crate::db::hydrate_pairing_token(&mut connection, skip_keychain) {
Ok((token, token_changed)) => {
if let Ok(mut pairing_token) = app_state.extension_pairing_token.write() {
*pairing_token = token.clone();
@@ -3077,7 +3078,7 @@ fn hydrate_extension_pairing_token(
Ok(PairingTokenHydration {
token,
token_changed,
persistent: true,
persistent: !skip_keychain,
error: None,
})
}
@@ -3893,7 +3894,6 @@ pub fn run() {
log::info!("Memory: {} MB total", sys.total_memory() / 1024 / 1024);
log::info!("App Version: {}", env!("CARGO_PKG_VERSION"));
log::info!("==========================");
build_main_tray(app.handle())
.map_err(|error| format!("failed to create tray menu: {error}"))?;
@@ -3901,7 +3901,8 @@ pub fn run() {
.map_err(|error| format!("failed to initialize persistence: {error}"))?;
let initial_pairing_token = {
let mut connection = database.lock()?;
match crate::db::hydrate_pairing_token(&mut connection, false) {
let skip_keychain = !crate::db::is_keychain_access_granted(&connection).unwrap_or(false);
match crate::db::hydrate_pairing_token(&mut connection, skip_keychain) {
Ok((token, _)) => token,
Err(error) => {
log::warn!(