Handle inability to inject script to all frames (#126)

This commit is contained in:
Maxim Baz
2019-04-19 12:52:15 +02:00
committed by GitHub
parent 3d487e504c
commit f030e4ca2c

View File

@@ -293,6 +293,27 @@ async function dispatchFocusOrSubmit(settings, request, allFrames, allowForeign)
} catch (e) {}
}
/**
* Inject script
*
* @param object settings Settings object
* @param boolean allFrames Inject in all frames
* @return object Cancellable promise
*/
async function injectScript(settings, allFrames) {
const MAX_WAIT = 1000;
return new Promise(async (resolve, reject) => {
const waitTimeout = setTimeout(reject, MAX_WAIT);
await chrome.tabs.executeScript(settings.tab.id, {
allFrames: allFrames,
file: "js/inject.dist.js"
});
clearTimeout(waitTimeout);
resolve(true);
});
}
/**
* Fill form fields
*
@@ -303,10 +324,19 @@ async function dispatchFocusOrSubmit(settings, request, allFrames, allowForeign)
*/
async function fillFields(settings, login, fields) {
// inject script
await chrome.tabs.executeScript(settings.tab.id, {
allFrames: true,
file: "js/inject.dist.js"
});
try {
await injectScript(settings, false);
} catch {
throw new Error("Unable to inject script in the top frame");
}
let injectedAllFrames = false;
try {
await injectScript(settings, true);
injectedAllFrames = true;
} catch {
// we'll proceed with trying to fill only the top frame
}
// build fill request
var fillRequest = {
@@ -326,43 +356,68 @@ async function fillFields(settings, login, fields) {
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
);
// try again using same-origin frames if we couldn't fill an "important" field
if (!filledFields.includes(importantFieldToFill)) {
allFrames = true;
filledFields = filledFields.concat(
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
);
}
if (injectedAllFrames) {
// try again using same-origin frames if we couldn't fill an "important" field
if (!filledFields.includes(importantFieldToFill)) {
allFrames = true;
filledFields = filledFields.concat(
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
);
}
// try again using all available frames if we couldn't fill an "important" field
if (
!filledFields.includes(importantFieldToFill) &&
settings.foreignFills[settings.host] !== false
) {
allowForeign = true;
filledFields = filledFields.concat(
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
);
// try again using all available frames if we couldn't fill an "important" field
if (
!filledFields.includes(importantFieldToFill) &&
settings.foreignFills[settings.host] !== false
) {
allowForeign = true;
filledFields = filledFields.concat(
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
);
}
}
// try again, but don't require a password field (if it was required until now)
if (!allowNoSecret) {
allowNoSecret = true;
// try again using same-origin frames
// try again using only the top frame
if (!filledFields.length) {
allFrames = false;
allowForeign = false;
filledFields = filledFields.concat(
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
);
}
// try again using all available frames
if (!filledFields.length && settings.foreignFills[settings.host] !== false) {
allowForeign = true;
filledFields = filledFields.concat(
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
);
if (injectedAllFrames) {
// try again using same-origin frames
if (!filledFields.length) {
allFrames = true;
filledFields = filledFields.concat(
await dispatchFill(
settings,
fillRequest,
allFrames,
allowForeign,
allowNoSecret
)
);
}
// try again using all available frames
if (!filledFields.length && settings.foreignFills[settings.host] !== false) {
allowForeign = true;
filledFields = filledFields.concat(
await dispatchFill(
settings,
fillRequest,
allFrames,
allowForeign,
allowNoSecret
)
);
}
}
}