Add browser extension gRPC bridge
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
function isVisibleInput(input) {
|
||||
if (!(input instanceof HTMLInputElement)) {
|
||||
return false;
|
||||
}
|
||||
if (input.disabled || input.readOnly) {
|
||||
return false;
|
||||
}
|
||||
const style = window.getComputedStyle(input);
|
||||
if (style.display === "none" || style.visibility === "hidden") {
|
||||
return false;
|
||||
}
|
||||
return input.offsetParent !== null || style.position === "fixed";
|
||||
}
|
||||
|
||||
function dispatchFillEvents(input) {
|
||||
input.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
input.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
}
|
||||
|
||||
function findPasswordInput() {
|
||||
return Array.from(document.querySelectorAll('input[type="password"]')).find(isVisibleInput) || null;
|
||||
}
|
||||
|
||||
function findUsernameInput(passwordInput) {
|
||||
const form = passwordInput?.form || null;
|
||||
const scope = form || document;
|
||||
const candidates = Array.from(scope.querySelectorAll('input[type="text"], input[type="email"], input:not([type])'))
|
||||
.filter(isVisibleInput);
|
||||
if (passwordInput) {
|
||||
const sameForm = candidates.find((input) => input.form === passwordInput.form);
|
||||
if (sameForm) {
|
||||
return sameForm;
|
||||
}
|
||||
}
|
||||
return candidates[0] || null;
|
||||
}
|
||||
|
||||
function fillCredential(credential) {
|
||||
const passwordInput = findPasswordInput();
|
||||
const usernameInput = findUsernameInput(passwordInput);
|
||||
|
||||
if (usernameInput && credential.username) {
|
||||
usernameInput.focus();
|
||||
usernameInput.value = credential.username;
|
||||
dispatchFillEvents(usernameInput);
|
||||
}
|
||||
if (passwordInput && credential.password) {
|
||||
passwordInput.focus();
|
||||
passwordInput.value = credential.password;
|
||||
dispatchFillEvents(passwordInput);
|
||||
}
|
||||
|
||||
if (!usernameInput && !passwordInput) {
|
||||
return { ok: false, error: "No fillable username or password fields were found." };
|
||||
}
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
(globalThis.browser ?? globalThis.chrome).runtime.onMessage.addListener((message, _sender, sendResponse) => {
|
||||
if (message?.type !== "keepassgo-fill-credential") {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
sendResponse(fillCredential(message.credential || {}));
|
||||
} catch (error) {
|
||||
sendResponse({ ok: false, error: error instanceof Error ? error.message : String(error) });
|
||||
}
|
||||
return false;
|
||||
});
|
||||
Reference in New Issue
Block a user