Fix fill-password: wrong host key, and silent failure
Two bugs made 'Fill saved password' do nothing: 1. HOST MISMATCH. Saving used location.hostname at submit time (e.g. accounts.google.com); filling derived the host from the app's configured URL (mail.google.com). The Keychain lookup always found nothing for any service with a separate auth domain. Fixed by storing the save-time hostname in App.saved_host and reading it back at fill time, falling back to default_scope for entries saved before this. 2. SILENT FAILURE. Every error path in the fillpw sentinel called only eprintln!, which is invisible to the user. A feature that fails silently is indistinguishable from one that is not wired up. Fixed by emitting a fill-error event; the shell shows it as a toast in the nav column, which is left of the stage and therefore always above native views.
This commit is contained in:
+21
@@ -32,6 +32,7 @@ export default function App() {
|
||||
const [downloads, setDownloads] = useState<Download[]>([]);
|
||||
const [offer, setOffer] = useState<PasswordOffer | null>(null);
|
||||
const [saved, setSaved] = useState<string | null>(null);
|
||||
const [fillError, setFillError] = useState<string | null>(null);
|
||||
|
||||
const stageRef = useRef<HTMLDivElement>(null);
|
||||
const booted = useRef(false);
|
||||
@@ -147,6 +148,11 @@ export default function App() {
|
||||
}),
|
||||
// A login was submitted. The password is held in Rust; this only asks.
|
||||
listen<PasswordOffer>("password-offer", (e) => setOffer(e.payload)),
|
||||
// Fill failed — show the reason rather than doing nothing silently.
|
||||
listen<string>("fill-error", (e) => {
|
||||
setFillError(e.payload);
|
||||
setTimeout(() => setFillError(null), 5000);
|
||||
}),
|
||||
|
||||
listen<{ id: number; name: string; path: string }>("download-started", (e) =>
|
||||
setDownloads((d) => [
|
||||
@@ -322,6 +328,21 @@ export default function App() {
|
||||
</Dialog>
|
||||
)}
|
||||
|
||||
{fillError && (
|
||||
/* Positioned within the nav column (left of the stage), so it is
|
||||
always above native views. The stage starts at x = collapsed ? rail
|
||||
: PANEL; this toast stays well within that. */
|
||||
<div
|
||||
role="alert"
|
||||
style={{ width: collapsed ? rail : 240 }}
|
||||
className="fixed bottom-4 left-0 z-[80] px-3"
|
||||
>
|
||||
<div className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-[12px] leading-snug text-red-700 shadow-md dark:border-red-900 dark:bg-red-950/60 dark:text-red-300">
|
||||
{fillError}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{settingsOpen && (
|
||||
<Settings
|
||||
config={config}
|
||||
|
||||
Reference in New Issue
Block a user