diff --git a/src/bg.js b/src/bg.js index 448b111..693e040 100644 --- a/src/bg.js +++ b/src/bg.js @@ -162,6 +162,12 @@ async function setup() { if (logging) console.log("bg calculated sitepw", bg, database, p, isSuperPw(superpw)); sendResponse(p); await Promise.resolve(); // To match the awaits in the other branches + } else if (request.cmd == "getUsername") { + let domainname = getdomainname(sender.origin || sender.url); + if (testMode) domainname = "alantheguru.alanhkarp.com"; + bg.settings = bgsettings(domainname); + sendResponse(bg.settings.username); + await Promise.resolve(); // To match the awaits in the other branches } else if (request.cmd === "reset") { // Used for testing, can't be in test.js becuase it needs to set local variables defaultSettings = clone(baseDefaultSettings); diff --git a/src/findpw.js b/src/findpw.js index 9ceec54..2cbc2e9 100644 --- a/src/findpw.js +++ b/src/findpw.js @@ -6,6 +6,7 @@ var clickSitePassword = "Click SitePassword"; var clickSitePasswordTitle = "Click on the SitePassword icon" var clickHere = "Click here for password"; var pasteHere = "Dbl-click or paste your password"; +var insertUsername = "Dbl-click for user name"; var sitepw = ""; var userid = ""; var maxidfields = 0; @@ -89,9 +90,6 @@ function startup(sendPageInfo) { // There is no reason to declare new mutation observers and listeners on every call. if (!mutationObserver) { cpi = countpwid(); - for (let i = 0; i < cpi.pwfields.length; i++) { - // cpi.pwfields[i].placeholder = "Testing " + i; // To test not overwriting existing placeholders - } // Firefox doesn't preserve sessionStorage across restarts of // the service worker. Sending periodic messages keeps it // alive, but there's no point to keep sending if there's an error. @@ -317,14 +315,20 @@ function countpwid() { var pwfields = []; var found = -1; var c = 0; + let firstVisible = null; let inputs = document.getElementsByTagName("input"); if (cpi.pwfields.length === 0 && inputs.length === 0) inputs = searchShadowRoots(document.body); for (var i = 0; i < inputs.length; i++) { - if (inputs[i].type && (inputs[i].type.toLowerCase() == "password")) { - visible = !isHidden(inputs[i]); + visible = !isHidden(inputs[i]); + // I'm only interested in visible text and email fields, + // and splitting the condition makes it easier to debug + if (visible && inputs[i].type === "text" || inputs[i].type === "email") { + if (!firstVisible) firstVisible = inputs[i]; + } + if (visible && inputs[i].type && (inputs[i].type.toLowerCase() === "password")) { if (logging) console.log(document.URL, Date.now() - start, "findpw found password field", i, inputs[i], visible); let pattern = inputs[i].getAttribute("pattern"); // Pattern [0-9]* is a PIN or SSN - if (visible && pattern !== "[0-9]*") { + if (pattern !== "[0-9]*") { if (self.origin === null || self.origin === "null") { inputs[i].type = "text"; inputs[i].value = "Untrusted: Input disabled."; @@ -371,6 +375,30 @@ function countpwid() { } } } + // Allow dbl click to fill in the username + // I already fill in the username if there are any password fields + if (c === 0 && firstVisible) { + let usernameField = firstVisible; + // Using await spreads async all over the place + wakeup().then(() => { + chrome.runtime.sendMessage({ "cmd": "getUsername" }).then((response) => { + if (chrome.runtime.lastError) console.log(document.URL, Date.now() - start, "findpw getUsername error", chrome.runtime.lastError); + if (response) { + if (!usernameField.placeholder) usernameField.placeholder = insertUsername; + if (!usernameField.title) usernameField.title = insertUsername; + usernameField.ondblclick = async function () { + let mutations = mutationObserver.takeRecords(); + fillfield(this, response); + let myMutations = mutationObserver.takeRecords(); + if (logging) console.log(document.URL, Date.now() - start, "findpw got username", this, response, myMutations); + handleMutations(mutations); + } + } else { + usernameField.ondblclick = null; + } + }); + }); + } if (logging) console.log(document.URL, Date.now() - start, "findpw: countpwid", c, pwfields, useridfield); return { pwfields: pwfields, idfield: useridfield }; } diff --git a/src/ssp.js b/src/ssp.js index 61cec6f..00b5335 100644 --- a/src/ssp.js +++ b/src/ssp.js @@ -179,16 +179,19 @@ get("mainpanel").onmouseleave = async function (event) { let phishingDomain = getPhishingDomain(get("sitename").value); if (logging) console.log("popup mainpanel mouseleave", phishingDomain); if (phishingDomain && saveSettings) openPhishingWarning(phishingDomain); - // Don't persist phishing sites if user mouses out of popup. - let element = document.elementFromPoint(event.pageX, event.pageY); + if (testMode) { + event.pageX = 0; + event.pageY = 0; + } + let element = event.pageX ? document.elementFromPoint(event.pageX, event.pageY) : null; if (logging) console.log("popup onmouseleave", phishingDomain, exporting, element); + // Don't persist if: phishing sites, exporting, the mouse is in the panel, or if event triggered by closing a help or instruction panel if (phishingDomain || exporting || element || !saveSettings) { if (logging) console.log("popup phishing mouseleave resolve mouseleaveResolver", phishingDomain, resolvers); saveSettings = true; if (resolvers.mouseleaveResolver) resolvers.mouseleaveResolver("mouseleavePromise"); return; } - saveSettings = true; get("superpw").focus(); if (logging) console.log("popup mainpanel mouseleave update bg", document.activeElement.id, bg); // window.onblur fires before I even have a chance to see the window, much less focus it @@ -260,8 +263,7 @@ get("domainnamemenuforget").onclick = function (e) { if (!get("domainname").value) return; msgon("forget"); let toforget = normalize(get("domainname").value); - addForgetItem(normalize(get("domainname").value)); -orgetItem(toforget); + addForgetItem(toforget); } get("domainnamemenuhelp").onclick = function (e) { helpItemOn("domainname");