Try to focus or submit form only once, after everything is filled (#54)
This commit is contained in:
@@ -81,6 +81,7 @@ function pathToDomain(path) {
|
|||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*
|
*
|
||||||
* @param int tabId Tab id
|
* @param int tabId Tab id
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
async function updateMatchingPasswordsCount(tabId) {
|
async function updateMatchingPasswordsCount(tabId) {
|
||||||
try {
|
try {
|
||||||
@@ -179,7 +180,7 @@ function saveRecent(settings, login, remove = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call injected form-fill code
|
* Call injected code to fill the form
|
||||||
*
|
*
|
||||||
* @param object settings Settings object
|
* @param object settings Settings object
|
||||||
* @param object fillRequest Fill request details
|
* @param object fillRequest Fill request details
|
||||||
@@ -188,13 +189,7 @@ function saveRecent(settings, login, remove = false) {
|
|||||||
* @param boolean allowNoSecret Allow forms that don't contain a password field
|
* @param boolean allowNoSecret Allow forms that don't contain a password field
|
||||||
* @return array list of filled fields
|
* @return array list of filled fields
|
||||||
*/
|
*/
|
||||||
async function dispatchFill(
|
async function dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret) {
|
||||||
settings,
|
|
||||||
fillRequest,
|
|
||||||
allFrames = false,
|
|
||||||
allowForeign = false,
|
|
||||||
allowNoSecret = false
|
|
||||||
) {
|
|
||||||
fillRequest = Object.assign(deepCopy(fillRequest), {
|
fillRequest = Object.assign(deepCopy(fillRequest), {
|
||||||
allowForeign: allowForeign,
|
allowForeign: allowForeign,
|
||||||
allowNoSecret: allowNoSecret,
|
allowNoSecret: allowNoSecret,
|
||||||
@@ -230,6 +225,27 @@ async function dispatchFill(
|
|||||||
return filledFields;
|
return filledFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call injected code to focus or submit the form
|
||||||
|
*
|
||||||
|
* @param object settings Settings object
|
||||||
|
* @param object focusOrSubmitRequest Focus or submit request details
|
||||||
|
* @param boolean allFrames Dispatch to all frames
|
||||||
|
* @param boolean allowForeign Allow foreign-origin iframes
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
async function dispatchFocusOrSubmit(settings, focusOrSubmitRequest, allFrames, allowForeign) {
|
||||||
|
focusOrSubmitRequest = Object.assign(deepCopy(focusOrSubmitRequest), {
|
||||||
|
allowForeign: allowForeign,
|
||||||
|
foreignFills: settings.foreignFills[settings.host] || {}
|
||||||
|
});
|
||||||
|
|
||||||
|
await chrome.tabs.executeScript(settings.tab.id, {
|
||||||
|
allFrames: allFrames,
|
||||||
|
code: `window.browserpass.focusOrSubmit(${JSON.stringify(focusOrSubmitRequest)});`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill form fields
|
* Fill form fields
|
||||||
*
|
*
|
||||||
@@ -256,34 +272,51 @@ async function fillFields(settings, login, fields) {
|
|||||||
var fillRequest = {
|
var fillRequest = {
|
||||||
origin: new URL(settings.tab.url).origin,
|
origin: new URL(settings.tab.url).origin,
|
||||||
login: login,
|
login: login,
|
||||||
fields: fields,
|
fields: fields
|
||||||
autoSubmit: getSetting("autoSubmit", login, settings)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// fill form via injected script
|
// fill form via injected script
|
||||||
var filledFields = await dispatchFill(settings, fillRequest);
|
let allFrames = false;
|
||||||
|
let allowForeign = false;
|
||||||
|
let allowNoSecret = false;
|
||||||
|
let filledFields = await dispatchFill(
|
||||||
|
settings,
|
||||||
|
fillRequest,
|
||||||
|
allFrames,
|
||||||
|
allowForeign,
|
||||||
|
allowNoSecret
|
||||||
|
);
|
||||||
|
|
||||||
// try again using same-origin frames if we couldn't fill a password field
|
// try again using same-origin frames if we couldn't fill a password field
|
||||||
if (!filledFields.includes("secret")) {
|
if (!filledFields.includes("secret")) {
|
||||||
filledFields = filledFields.concat(await dispatchFill(settings, fillRequest, true));
|
allFrames = true;
|
||||||
|
filledFields = filledFields.concat(
|
||||||
|
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// try again using all available frames if we couldn't fill a password field
|
// try again using all available frames if we couldn't fill a password field
|
||||||
if (!filledFields.includes("secret") && settings.foreignFills[settings.host] !== false) {
|
if (!filledFields.includes("secret") && settings.foreignFills[settings.host] !== false) {
|
||||||
filledFields = filledFields.concat(await dispatchFill(settings, fillRequest, true, true));
|
allowForeign = true;
|
||||||
|
filledFields = filledFields.concat(
|
||||||
|
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// try again using same-origin frames, and don't require a password field
|
// try again using same-origin frames, and don't require a password field
|
||||||
if (!filledFields.length) {
|
if (!filledFields.length) {
|
||||||
|
allowForeign = false;
|
||||||
|
allowNoSecret = true;
|
||||||
filledFields = filledFields.concat(
|
filledFields = filledFields.concat(
|
||||||
await dispatchFill(settings, fillRequest, true, false, true)
|
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// try again using all available frames, and don't require a password field
|
// try again using all available frames, and don't require a password field
|
||||||
if (!filledFields.length && settings.foreignFills[settings.host] !== false) {
|
if (!filledFields.length && settings.foreignFills[settings.host] !== false) {
|
||||||
|
allowForeign = true;
|
||||||
filledFields = filledFields.concat(
|
filledFields = filledFields.concat(
|
||||||
await dispatchFill(settings, fillRequest, true, true, true)
|
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,6 +324,15 @@ async function fillFields(settings, login, fields) {
|
|||||||
throw new Error(`No fillable forms available for fields: ${fields.join(", ")}`);
|
throw new Error(`No fillable forms available for fields: ${fields.join(", ")}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build focus or submit request
|
||||||
|
let focusOrSubmitRequest = {
|
||||||
|
origin: new URL(settings.tab.url).origin,
|
||||||
|
autoSubmit: getSetting("autoSubmit", login, settings)
|
||||||
|
};
|
||||||
|
|
||||||
|
// try to focus or submit form with the settings that were used to fill it
|
||||||
|
await dispatchFocusOrSubmit(settings, focusOrSubmitRequest, allFrames, allowForeign);
|
||||||
|
|
||||||
return filledFields;
|
return filledFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -126,6 +126,29 @@
|
|||||||
result.filledFields.push("secret");
|
result.filledFields.push("secret");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// finished filling things successfully
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Focus submit button, and maybe click on it (based on user settings)
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
*
|
||||||
|
* @param object request Form fill request
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function focusOrSubmit(request) {
|
||||||
|
// get the login form
|
||||||
|
var loginForm = form();
|
||||||
|
|
||||||
|
// ensure the origin is the same or allowed
|
||||||
|
if (window.location.origin !== request.origin) {
|
||||||
|
if (!request.allowForeign || request.foreignFills[window.location.origin] === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check for multiple password fields in the login form
|
// check for multiple password fields in the login form
|
||||||
var password_inputs = queryAllVisible(document, PASSWORD_FIELDS, loginForm);
|
var password_inputs = queryAllVisible(document, PASSWORD_FIELDS, loginForm);
|
||||||
if (password_inputs.length > 1) {
|
if (password_inputs.length > 1) {
|
||||||
@@ -156,9 +179,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// finished filling things successfully
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -333,6 +353,7 @@
|
|||||||
|
|
||||||
// set window object
|
// set window object
|
||||||
window.browserpass = {
|
window.browserpass = {
|
||||||
fillLogin: fillLogin
|
fillLogin: fillLogin,
|
||||||
|
focusOrSubmit: focusOrSubmit
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
Reference in New Issue
Block a user