Store recent info in background context (#32)

Solves updating recent info when popup gets prematurely closed, e.g. by the "foreign origin" confirmation dialog

Fixes #30
This commit is contained in:
Maxim Baz
2019-02-23 20:55:19 +01:00
committed by GitHub
parent 8fa36bc286
commit b2c9765a36
2 changed files with 53 additions and 53 deletions

View File

@@ -2,6 +2,7 @@
"use strict"; "use strict";
require("chrome-extension-async"); require("chrome-extension-async");
var sha1 = require("sha1");
// native application id // native application id
var appID = "com.github.browserpass.native"; var appID = "com.github.browserpass.native";
@@ -60,6 +61,34 @@ function copyToClipboard(text) {
document.execCommand("copy"); document.execCommand("copy");
} }
/**
* Save login to recent list for current domain
*
* @since 3.0.0
*
* @param object settings Settings object
* @param string host Hostname
* @param object login Login object
* @param bool remove Remove this item from recent history
* @return void
*/
function saveRecent(settings, host, login, remove = false) {
var ignoreInterval = 60000; // 60 seconds - don't increment counter twice within this window
// save store timestamp
localStorage.setItem("recent:" + login.store.id, JSON.stringify(Date.now()));
// update login usage count & timestamp
if (Date.now() > login.recent.when + ignoreInterval) {
login.recent.count++;
}
login.recent.when = Date.now();
settings.recent[sha1(host + sha1(login.store.id + sha1(login.login)))] = login.recent;
// save to local storage
localStorage.setItem("recent", JSON.stringify(settings.recent));
}
/** /**
* Call injected form-fill code * Call injected form-fill code
* *
@@ -175,6 +204,21 @@ function getLocalSettings() {
} }
} }
for (var storeId in settings.stores) {
var when = localStorage.getItem("recent:" + storeId);
if (when) {
settings.stores[storeId].when = JSON.parse(when);
} else {
settings.stores[storeId].when = 0;
}
}
settings.recent = localStorage.getItem("recent");
if (settings.recent) {
settings.recent = JSON.parse(settings.recent);
} else {
settings.recent = {};
}
return settings; return settings;
} }
@@ -287,6 +331,7 @@ async function handleMessage(settings, message, sendResponse) {
case "copyPassword": case "copyPassword":
try { try {
copyToClipboard(message.login.fields.secret); copyToClipboard(message.login.fields.secret);
saveRecent(settings, message.host, message.login);
sendResponse({ status: "ok" }); sendResponse({ status: "ok" });
} catch (e) { } catch (e) {
sendResponse({ sendResponse({
@@ -298,6 +343,7 @@ async function handleMessage(settings, message, sendResponse) {
case "copyUsername": case "copyUsername":
try { try {
copyToClipboard(message.login.fields.login); copyToClipboard(message.login.fields.login);
saveRecent(settings, message.host, message.login);
sendResponse({ status: "ok" }); sendResponse({ status: "ok" });
} catch (e) { } catch (e) {
sendResponse({ sendResponse({
@@ -343,6 +389,7 @@ async function handleMessage(settings, message, sendResponse) {
// dispatch initial fill request // dispatch initial fill request
var filledFields = await fillFields(targetTab, message.login, ["login", "secret"]); var filledFields = await fillFields(targetTab, message.login, ["login", "secret"]);
saveRecent(settings, message.host, message.login);
// no need to check filledFields, because fillFields() already throws an error if empty // no need to check filledFields, because fillFields() already throws an error if empty
sendResponse({ status: "ok", filledFields: filledFields }); sendResponse({ status: "ok", filledFields: filledFields });

View File

@@ -14,22 +14,12 @@ chrome.tabs.query({ active: true, currentWindow: true }, async function(tabs) {
throw new Error(response.message); throw new Error(response.message);
} }
var settings = response.settings; var settings = response.settings;
// Set additional settings only visible in the popup context,
// if necessary these need to be additionally passed to the background script
settings.tab = tabs[0]; settings.tab = tabs[0];
settings.host = new URL(settings.tab.url).hostname; settings.host = new URL(settings.tab.url).hostname;
for (var storeId in settings.stores) {
var when = localStorage.getItem("recent:" + storeId);
if (when) {
settings.stores[storeId].when = JSON.parse(when);
} else {
settings.stores[storeId].when = 0;
}
}
settings.recent = localStorage.getItem("recent");
if (settings.recent) {
settings.recent = JSON.parse(settings.recent);
} else {
settings.recent = {};
}
run(settings); run(settings);
} catch (e) { } catch (e) {
handleError(e); handleError(e);
@@ -98,10 +88,6 @@ async function run(settings) {
var logins = []; var logins = [];
var index = 0; var index = 0;
var recent = localStorage.getItem("recent:" + settings.host);
if (recent) {
recent = JSON.parse(recent);
}
for (var storeId in response.files) { for (var storeId in response.files) {
for (var key in response.files[storeId]) { for (var key in response.files[storeId]) {
// set login fields // set login fields
@@ -135,33 +121,6 @@ async function run(settings) {
} }
} }
/**
* Save login to recent list for current domain
*
* @since 3.0.0
*
* @param object settings Settings object
* @param object login Login object
* @param bool remove Remove this item from recent history
* @return void
*/
function saveRecent(settings, login, remove = false) {
var ignoreInterval = 60000; // 60 seconds - don't increment counter twice within this window
// save store timestamp
localStorage.setItem("recent:" + login.store.id, JSON.stringify(Date.now()));
// update login usage count & timestamp
if (Date.now() > login.recent.when + ignoreInterval) {
login.recent.count++;
}
login.recent.when = Date.now();
settings.recent[sha1(settings.host + sha1(login.store.id + sha1(login.login)))] = login.recent;
// save to local storage
localStorage.setItem("recent", JSON.stringify(settings.recent));
}
/** /**
* Do a login action * Do a login action
* *
@@ -194,18 +153,12 @@ async function withLogin(action) {
// hand off action to background script // hand off action to background script
var response = await chrome.runtime.sendMessage({ var response = await chrome.runtime.sendMessage({
action: action, action: action,
login: this.login login: this.login,
host: this.settings.host
}); });
if (response.status != "ok") { if (response.status != "ok") {
throw new Error(response.message); throw new Error(response.message);
} else { } else {
switch (action) {
// fall through to update recent
case "fill":
case "copyPassword":
case "copyUsername":
saveRecent(this.settings, this.login);
}
window.close(); window.close();
} }
} catch (e) { } catch (e) {