Files
keepassgo/browser/extension/popup.js
T
2026-04-11 00:52:01 -07:00

102 lines
3.2 KiB
JavaScript

const extPopup = globalThis.browser ?? globalThis.chrome;
function runtimeSend(message) {
return new Promise((resolve, reject) => {
extPopup.runtime.sendMessage(message, (response) => {
const error = extPopup.runtime.lastError;
if (error) {
reject(new Error(error.message));
return;
}
resolve(response);
});
});
}
function hostFromURL(rawURL) {
try {
return new URL(rawURL).host || rawURL;
} catch (_error) {
return rawURL || "Current page";
}
}
function setStatus(title, message, tone) {
const card = document.getElementById("status-card");
card.dataset.tone = tone || "neutral";
document.getElementById("status-title").textContent = title;
document.getElementById("status-message").textContent = message;
}
function renderMatches(state) {
const root = document.getElementById("matches");
root.textContent = "";
if (!Array.isArray(state.matches) || state.matches.length === 0) {
const empty = document.createElement("p");
empty.className = "subtle";
empty.textContent = "No matching entries for this page.";
root.appendChild(empty);
return;
}
for (const match of state.matches) {
const row = document.createElement("button");
row.type = "button";
row.className = "match-row";
row.innerHTML = `
<span class="match-main">
<strong>${match.title}</strong>
<span class="subtle">${match.username || "No username"}</span>
</span>
<span class="quality">${match.quality || ""}</span>
`;
row.addEventListener("click", async () => {
row.disabled = true;
try {
const result = await runtimeSend({ type: "keepassgo-fill-entry", entryId: match.id });
if (!result?.success) {
throw new Error(result?.error || "Fill failed.");
}
setStatus("Filled", `${match.title} was sent to the current page.`, "ready");
} catch (error) {
setStatus("Fill failed", error instanceof Error ? error.message : String(error), "error");
} finally {
row.disabled = false;
}
});
root.appendChild(row);
}
}
async function main() {
try {
const state = await runtimeSend({ type: "keepassgo-popup-state" });
document.getElementById("page-host").textContent = hostFromURL(state.pageUrl || "");
if (!state.configured) {
setStatus("Configure access", state.error || "Set the API token in extension settings.", "warning");
renderMatches({ matches: [] });
return;
}
if (!state.success) {
setStatus("KeePassGO unavailable", state.error || "The native host could not reach KeePassGO.", "error");
renderMatches({ matches: [] });
return;
}
if (state.status?.locked) {
setStatus("Vault locked", "Unlock KeePassGO, then open the popup again.", "warning");
renderMatches({ matches: [] });
return;
}
const count = Array.isArray(state.matches) ? state.matches.length : 0;
setStatus("Ready", count === 0 ? "KeePassGO is connected." : `${count} matching entr${count === 1 ? "y" : "ies"} found.`, "ready");
renderMatches(state);
} catch (error) {
setStatus("Error", error instanceof Error ? error.message : String(error), "error");
renderMatches({ matches: [] });
}
}
void main();