mirror of
https://github.com/nimbold/Firelink.git
synced 2026-08-29 03:57:11 +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>,
|
app_state: tauri::State<'_, AppState>,
|
||||||
) -> Result<PairingTokenHydration, String> {
|
) -> Result<PairingTokenHydration, String> {
|
||||||
let mut connection = database.lock()?;
|
let mut connection = database.lock()?;
|
||||||
// Always skip the keychain during automatic hydration so the operating
|
let skip_keychain = !crate::db::is_keychain_access_granted(&connection).unwrap_or(false);
|
||||||
// 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;
|
|
||||||
match crate::db::hydrate_pairing_token(&mut connection, skip_keychain) {
|
match crate::db::hydrate_pairing_token(&mut connection, skip_keychain) {
|
||||||
Ok((token, token_changed)) => {
|
Ok((token, token_changed)) => {
|
||||||
if let Ok(mut pairing_token) = app_state.extension_pairing_token.write() {
|
if let Ok(mut pairing_token) = app_state.extension_pairing_token.write() {
|
||||||
|
|||||||
@@ -19,8 +19,15 @@ export const KeychainPermissionModal: React.FC = () => {
|
|||||||
try {
|
try {
|
||||||
const result = await invoke('grant_keychain_access');
|
const result = await invoke('grant_keychain_access');
|
||||||
if (result.persistent) {
|
if (result.persistent) {
|
||||||
useSettingsStore.setState({ keychainAccessGranted: true });
|
// Set all keychain-related state directly from the grant result
|
||||||
await useSettingsStore.getState().hydratePairingToken();
|
// 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);
|
setShowKeychainModal(false);
|
||||||
} else {
|
} else {
|
||||||
setError(result.error || 'Failed to grant keychain access.');
|
setError(result.error || 'Failed to grant keychain access.');
|
||||||
|
|||||||
Reference in New Issue
Block a user