Add browser save and update workflow
This commit is contained in:
+87
-11
@@ -43,6 +43,12 @@ function matchSubtitle(match) {
|
||||
return parts.join(" · ") || "No username";
|
||||
}
|
||||
|
||||
function saveCardLabel(pendingSave) {
|
||||
return pendingSave?.mode === "update"
|
||||
? `Update ${pendingSave.title || "Login"}`
|
||||
: "Save Login";
|
||||
}
|
||||
|
||||
function renderMatchList(root, matches, options = {}) {
|
||||
const targetTabID = popupTabID();
|
||||
const emptyMessage = options.emptyMessage || "No matching entries.";
|
||||
@@ -75,19 +81,23 @@ function renderMatchList(root, matches, options = {}) {
|
||||
row.appendChild(quality);
|
||||
row.addEventListener("click", async () => {
|
||||
row.disabled = true;
|
||||
setStatus("Approval may be required", "KeePassGO will prompt if this token needs approval before fill.", "warning");
|
||||
try {
|
||||
const result = await runtimeSend({
|
||||
type: "keepassgo-fill-entry",
|
||||
entryId: match.id,
|
||||
tabId: targetTabID
|
||||
});
|
||||
if (!result?.success) {
|
||||
throw new Error(result?.error || "Fill failed.");
|
||||
if (typeof options.onSelect === "function") {
|
||||
await options.onSelect(match, targetTabID);
|
||||
} else {
|
||||
setStatus("Approval may be required", "KeePassGO will prompt if this token needs approval before fill.", "warning");
|
||||
const result = await runtimeSend({
|
||||
type: "keepassgo-fill-entry",
|
||||
entryId: match.id,
|
||||
tabId: targetTabID
|
||||
});
|
||||
if (!result?.success) {
|
||||
throw new Error(result?.error || "Fill failed.");
|
||||
}
|
||||
setStatus("Filled", `${match.title} was sent to the current page.`, "ready");
|
||||
}
|
||||
setStatus("Filled", `${match.title} was sent to the current page.`, "ready");
|
||||
} catch (error) {
|
||||
setStatus("Fill failed", error instanceof Error ? error.message : String(error), "error");
|
||||
setStatus(options.onSelect ? "Save failed" : "Fill failed", error instanceof Error ? error.message : String(error), "error");
|
||||
} finally {
|
||||
row.disabled = false;
|
||||
}
|
||||
@@ -100,7 +110,30 @@ function renderMatches(state) {
|
||||
const emptyMessage = state.pageHasLoginForm
|
||||
? "No matching entries for this page."
|
||||
: "No login fields detected on this page.";
|
||||
renderMatchList(document.getElementById("matches"), state.matches, { emptyMessage });
|
||||
const root = document.getElementById("matches");
|
||||
if (state.pendingSave) {
|
||||
renderMatchList(root, state.matches, {
|
||||
emptyMessage,
|
||||
onSelect: async (match, targetTabID) => {
|
||||
const result = await runtimeSend({
|
||||
type: "keepassgo-save-login",
|
||||
tabId: targetTabID,
|
||||
selectedMatch: {
|
||||
id: match.id,
|
||||
title: match.title,
|
||||
path: Array.isArray(match.path) ? match.path : []
|
||||
}
|
||||
});
|
||||
if (!result?.success) {
|
||||
throw new Error(result?.error || "Save failed.");
|
||||
}
|
||||
setStatus("Saved", `${state.pendingSave.title || "Login"} is now in KeePassGO.`, "ready");
|
||||
document.getElementById("save-card").hidden = true;
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
renderMatchList(root, state.matches, { emptyMessage });
|
||||
}
|
||||
|
||||
function renderSearchResults(results, query) {
|
||||
@@ -135,6 +168,46 @@ function renderPageHint(state) {
|
||||
hint.textContent = "Open a sign-in page to see KeePassGO suggestions here.";
|
||||
}
|
||||
|
||||
function renderPendingSave(state) {
|
||||
const card = document.getElementById("save-card");
|
||||
const message = document.getElementById("save-message");
|
||||
const action = document.getElementById("save-action");
|
||||
const pendingSave = state.pendingSave;
|
||||
if (!pendingSave) {
|
||||
card.hidden = true;
|
||||
action.onclick = null;
|
||||
return;
|
||||
}
|
||||
card.hidden = false;
|
||||
action.textContent = saveCardLabel(pendingSave);
|
||||
if (pendingSave.mode === "update") {
|
||||
message.textContent = `KeePassGO can update ${pendingSave.title || "this login"} with the submitted password.`;
|
||||
} else if (Array.isArray(pendingSave.path) && pendingSave.path.length > 0) {
|
||||
message.textContent = `KeePassGO can save this login in ${pendingSave.path.join(" / ")}. Search the vault to choose a different group if needed.`;
|
||||
} else {
|
||||
message.textContent = "Search the vault below to choose a group for this submitted login.";
|
||||
}
|
||||
action.disabled = pendingSave.mode !== "update" && (!Array.isArray(pendingSave.path) || pendingSave.path.length === 0);
|
||||
action.onclick = async () => {
|
||||
action.disabled = true;
|
||||
try {
|
||||
const result = await runtimeSend({
|
||||
type: "keepassgo-save-login",
|
||||
tabId: popupTabID()
|
||||
});
|
||||
if (!result?.success) {
|
||||
throw new Error(result?.error || "Save failed.");
|
||||
}
|
||||
setStatus("Saved", `${pendingSave.title || "Login"} is now in KeePassGO.`, "ready");
|
||||
card.hidden = true;
|
||||
} catch (error) {
|
||||
setStatus("Save failed", error instanceof Error ? error.message : String(error), "error");
|
||||
} finally {
|
||||
action.disabled = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function popupTabID() {
|
||||
const rawValue = new URLSearchParams(window.location.search).get("tabId");
|
||||
if (rawValue === null) {
|
||||
@@ -183,6 +256,7 @@ async function main() {
|
||||
});
|
||||
document.getElementById("page-host").textContent = hostFromURL(state.pageUrl || "");
|
||||
renderPageHint(state);
|
||||
renderPendingSave(state);
|
||||
|
||||
if (!state.configured) {
|
||||
setStatus("Configure access", state.error || "Set the API token in extension settings.", "warning");
|
||||
@@ -208,6 +282,8 @@ async function main() {
|
||||
const count = Array.isArray(state.matches) ? state.matches.length : 0;
|
||||
if (!state.pageHasLoginForm) {
|
||||
setStatus("Ready", "KeePassGO is connected. Open a login form to check for matches.", "ready");
|
||||
} else if (state.pendingSave) {
|
||||
setStatus("Save submitted login", state.pendingSave.mode === "update" ? `Update ${state.pendingSave.title || "this login"} or pick a different target below.` : "Save this submitted login or search below to choose a target entry.", "ready");
|
||||
} else if (count === 0) {
|
||||
setStatus("Checked this page", "KeePassGO did not find a matching login for this form.", "ready");
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user