fix(ui): bake password-manager autofill guard into PasswordInput

Config/secret fields (BYOK API keys, webhook secrets, ntfy tokens) pass no
autocomplete token, so PasswordInput now defaults to autoComplete=off plus
data-bwignore / data-1p-ignore / data-lpignore for them — Bitwarden /
1Password / LastPass no longer offer to fill or save a config secret.
Credential fields (login, register, password change) pass a real token and
keep manager integration untouched. One change covers every secret call site.
This commit is contained in:
Marc-André Bombeck committed 2026-07-08 23:47:46 +02:00
1 parent dbc2b15b1b
commit 9f4c7e48fe
2 files changed
+58

No files matched your search

@@ -0,0 +1,44 @@
import { describe, it, expect } from "vitest";
import { renderToStaticMarkup } from "react-dom/server";
import { I18nProvider } from "@/lib/i18n/context";
import { PasswordInput } from "../password-input";
/**
* PasswordInput bakes the password-manager autofill guard in by default so
* BYOK API keys / webhook secrets / ntfy tokens (config secrets, not
* credentials) are never offered up to Bitwarden / 1Password / LastPass.
* Credential fields that pass a real autocomplete token keep manager
* integration.
*/
function render(node: React.ReactNode) {
return renderToStaticMarkup(
<I18nProvider initialLocale="en">{node}</I18nProvider>,
);
}
describe("PasswordInput", () => {
it("suppresses password managers by default for config secrets", () => {
const html = render(<PasswordInput id="ntfy-token" />);
expect(html).toMatch(/autocomplete="off"/i);
expect(html).toContain("data-bwignore");
expect(html).toContain("data-1p-ignore");
expect(html).toContain('data-lpignore="true"');
});
it("treats an explicit autoComplete=off as a config secret too", () => {
const html = render(<PasswordInput id="tg-token" autoComplete="off" />);
expect(html).toContain("data-bwignore");
expect(html).toContain("data-1p-ignore");
});
it("keeps manager integration for credential fields", () => {
const html = render(
<PasswordInput id="current-password" autoComplete="current-password" />,
);
expect(html).toMatch(/autocomplete="current-password"/i);
expect(html).not.toContain("data-bwignore");
expect(html).not.toContain("data-1p-ignore");
expect(html).not.toContain("data-lpignore");
});
});