mirror of
https://github.com/nimbold/Firelink.git
synced 2026-07-26 12:08:27 +00:00
fix: stop keychain modal on every launch and fix grant-access loop
- Revert hydrate_extension_pairing_token to consult the DB's keychainAccessGranted flag instead of unconditionally skipping the keychain. When the flag is true the backend tries the keychain; if macOS trusts the current binary (no code-signature change) the read succeeds silently and the modal is suppressed. When the flag is false the keychain is skipped and the modal is shown exactly once. - Fix the Grant Access button in the KeychainPermissionModal by writing the result (token, persistent flag) directly into the store instead of calling hydratePairingToken() again. The re-hydration raced with Zustand's async persist middleware, which could read keychainAccessGranted=false from the DB and flip persistent back to false, re‑showing the modal in an endless loop. - The scheduler defaults (enabled: false) were already correct in both the Rust default_settings() and the frontend Zustand store; no code change needed.
This commit is contained in:
@@ -3435,12 +3435,7 @@ fn hydrate_extension_pairing_token(
|
||||
app_state: tauri::State<'_, AppState>,
|
||||
) -> Result<PairingTokenHydration, String> {
|
||||
let mut connection = database.lock()?;
|
||||
// Always skip the keychain during automatic hydration so the operating
|
||||
// system never presents a credential-access prompt before the app's own
|
||||
// modal is visible. The frontend will display the KeychainPermissionModal
|
||||
// and only call grant_keychain_access — which touches the keychain — after
|
||||
// the user explicitly clicks "Grant Access".
|
||||
let skip_keychain = true;
|
||||
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() {
|
||||
|
||||
@@ -19,8 +19,15 @@ export const KeychainPermissionModal: React.FC = () => {
|
||||
try {
|
||||
const result = await invoke('grant_keychain_access');
|
||||
if (result.persistent) {
|
||||
useSettingsStore.setState({ keychainAccessGranted: true });
|
||||
await useSettingsStore.getState().hydratePairingToken();
|
||||
// Set all keychain-related state directly from the grant result
|
||||
// instead of calling hydratePairingToken() again, which would
|
||||
// re-read the DB before Zustand's persist middleware has written
|
||||
// keychainAccessGranted and could flip persistent back to false.
|
||||
useSettingsStore.setState({
|
||||
keychainAccessGranted: true,
|
||||
extensionPairingToken: result.token,
|
||||
isPairingTokenPersistent: true
|
||||
});
|
||||
setShowKeychainModal(false);
|
||||
} else {
|
||||
setError(result.error || 'Failed to grant keychain access.');
|
||||
|
||||
Reference in New Issue
Block a user