Support OpenID (#70)
This commit is contained in:
@@ -278,13 +278,6 @@ async function dispatchFocusOrSubmit(settings, request, allFrames, allowForeign)
|
|||||||
* @return array List of filled fields
|
* @return array List of filled fields
|
||||||
*/
|
*/
|
||||||
async function fillFields(settings, login, fields) {
|
async function fillFields(settings, login, fields) {
|
||||||
// check that required fields are present
|
|
||||||
for (var field of fields) {
|
|
||||||
if (login.fields[field] === null) {
|
|
||||||
throw new Error(`Required field is missing: ${field}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// inject script
|
// inject script
|
||||||
await chrome.tabs.executeScript(settings.tab.id, {
|
await chrome.tabs.executeScript(settings.tab.id, {
|
||||||
allFrames: true,
|
allFrames: true,
|
||||||
@@ -298,49 +291,55 @@ async function fillFields(settings, login, fields) {
|
|||||||
fields: fields
|
fields: fields
|
||||||
};
|
};
|
||||||
|
|
||||||
// fill form via injected script
|
|
||||||
let allFrames = false;
|
let allFrames = false;
|
||||||
let allowForeign = false;
|
let allowForeign = false;
|
||||||
let allowNoSecret = false;
|
let allowNoSecret = !fields.includes("secret");
|
||||||
let filledFields = await dispatchFill(
|
let filledFields = [];
|
||||||
settings,
|
let importantFieldToFill = fields.includes("openid") ? "openid" : "secret";
|
||||||
fillRequest,
|
|
||||||
allFrames,
|
// fill form via injected script
|
||||||
allowForeign,
|
filledFields = filledFields.concat(
|
||||||
allowNoSecret
|
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 an "important" field
|
||||||
if (!filledFields.includes("secret")) {
|
if (!filledFields.includes(importantFieldToFill)) {
|
||||||
allFrames = true;
|
allFrames = true;
|
||||||
filledFields = filledFields.concat(
|
filledFields = filledFields.concat(
|
||||||
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
|
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 an "important" field
|
||||||
if (!filledFields.includes("secret") && settings.foreignFills[settings.host] !== false) {
|
if (
|
||||||
|
!filledFields.includes(importantFieldToFill) &&
|
||||||
|
settings.foreignFills[settings.host] !== false
|
||||||
|
) {
|
||||||
allowForeign = true;
|
allowForeign = true;
|
||||||
filledFields = filledFields.concat(
|
filledFields = filledFields.concat(
|
||||||
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
|
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// try again using same-origin frames, and don't require a password field
|
// try again, but don't require a password field (if it was required until now)
|
||||||
if (!filledFields.length) {
|
if (!allowNoSecret) {
|
||||||
allowForeign = false;
|
|
||||||
allowNoSecret = true;
|
allowNoSecret = true;
|
||||||
filledFields = filledFields.concat(
|
|
||||||
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// try again using all available frames, and don't require a password field
|
// try again using same-origin frames
|
||||||
if (!filledFields.length && settings.foreignFills[settings.host] !== false) {
|
if (!filledFields.length) {
|
||||||
allowForeign = true;
|
allowForeign = false;
|
||||||
filledFields = filledFields.concat(
|
filledFields = filledFields.concat(
|
||||||
await dispatchFill(settings, fillRequest, allFrames, allowForeign, allowNoSecret)
|
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 (!filledFields.length) {
|
if (!filledFields.length) {
|
||||||
@@ -350,7 +349,8 @@ async function fillFields(settings, login, fields) {
|
|||||||
// build focus or submit request
|
// build focus or submit request
|
||||||
let focusOrSubmitRequest = {
|
let focusOrSubmitRequest = {
|
||||||
origin: new URL(settings.tab.url).origin,
|
origin: new URL(settings.tab.url).origin,
|
||||||
autoSubmit: getSetting("autoSubmit", login, settings)
|
autoSubmit: getSetting("autoSubmit", login, settings),
|
||||||
|
filledFields: filledFields
|
||||||
};
|
};
|
||||||
|
|
||||||
// try to focus or submit form with the settings that were used to fill it
|
// try to focus or submit form with the settings that were used to fill it
|
||||||
@@ -675,8 +675,10 @@ async function handleMessage(settings, message, sendResponse) {
|
|||||||
break;
|
break;
|
||||||
case "fill":
|
case "fill":
|
||||||
try {
|
try {
|
||||||
|
let fields = message.login.fields.openid ? ["openid"] : ["login", "secret"];
|
||||||
|
|
||||||
// dispatch initial fill request
|
// dispatch initial fill request
|
||||||
var filledFields = await fillFields(settings, message.login, ["login", "secret"]);
|
var filledFields = await fillFields(settings, message.login, fields);
|
||||||
saveRecent(settings, message.login);
|
saveRecent(settings, 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
|
||||||
@@ -751,6 +753,7 @@ async function parseFields(settings, login) {
|
|||||||
login.fields = {
|
login.fields = {
|
||||||
secret: ["secret", "password", "pass"],
|
secret: ["secret", "password", "pass"],
|
||||||
login: ["login", "username", "user", "email"],
|
login: ["login", "username", "user", "email"],
|
||||||
|
openid: ["openid"],
|
||||||
url: ["url", "uri", "website", "site", "link", "launch"]
|
url: ["url", "uri", "website", "site", "link", "launch"]
|
||||||
};
|
};
|
||||||
login.settings = {
|
login.settings = {
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
(function() {
|
(function() {
|
||||||
const FORM_MARKERS = ["login", "log-in", "log_in", "signin", "sign-in", "sign_in"];
|
const FORM_MARKERS = ["login", "log-in", "log_in", "signin", "sign-in", "sign_in"];
|
||||||
|
const OPENID_FIELDS = {
|
||||||
|
selectors: ["input[name*=openid i]", "input[id*=openid i]", "input[class*=openid i]"],
|
||||||
|
types: ["text"]
|
||||||
|
};
|
||||||
const USERNAME_FIELDS = {
|
const USERNAME_FIELDS = {
|
||||||
selectors: [
|
selectors: [
|
||||||
"input[id*=openid i]",
|
|
||||||
"input[name*=openid i]",
|
|
||||||
"input[class*=openid i]",
|
|
||||||
|
|
||||||
"input[name*=login i]",
|
"input[name*=login i]",
|
||||||
"input[name*=user i]",
|
"input[name*=user i]",
|
||||||
"input[name*=email i]",
|
"input[name*=email i]",
|
||||||
@@ -25,7 +25,9 @@
|
|||||||
selectors: ["input[type=password i]"]
|
selectors: ["input[type=password i]"]
|
||||||
};
|
};
|
||||||
const INPUT_FIELDS = {
|
const INPUT_FIELDS = {
|
||||||
selectors: PASSWORD_FIELDS.selectors.concat(USERNAME_FIELDS.selectors)
|
selectors: PASSWORD_FIELDS.selectors
|
||||||
|
.concat(USERNAME_FIELDS.selectors)
|
||||||
|
.concat(OPENID_FIELDS.selectors)
|
||||||
};
|
};
|
||||||
const SUBMIT_FIELDS = {
|
const SUBMIT_FIELDS = {
|
||||||
selectors: [
|
selectors: [
|
||||||
@@ -84,10 +86,17 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// get the login form
|
// get the login form
|
||||||
var loginForm = form();
|
let loginForm = undefined;
|
||||||
|
if (request.fields.includes("openid")) {
|
||||||
|
// this is an attempt to fill a form containing only openid field
|
||||||
|
loginForm = form(OPENID_FIELDS);
|
||||||
|
} else {
|
||||||
|
// this is an attempt to fill a regular login form
|
||||||
|
loginForm = form(INPUT_FIELDS);
|
||||||
|
}
|
||||||
|
|
||||||
// don't attempt to fill non-secret forms unless non-secret filling is allowed
|
// don't attempt to fill non-secret forms unless non-secret filling is allowed
|
||||||
if (!find(PASSWORD_FIELDS, loginForm) && !request.allowNoSecret) {
|
if (!request.allowNoSecret && !find(PASSWORD_FIELDS, loginForm)) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,6 +135,14 @@
|
|||||||
result.filledFields.push("secret");
|
result.filledFields.push("secret");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fill openid field
|
||||||
|
if (
|
||||||
|
request.fields.includes("openid") &&
|
||||||
|
update(OPENID_FIELDS, request.login.fields.openid, loginForm)
|
||||||
|
) {
|
||||||
|
result.filledFields.push("openid");
|
||||||
|
}
|
||||||
|
|
||||||
// finished filling things successfully
|
// finished filling things successfully
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -144,7 +161,14 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// get the login form
|
// get the login form
|
||||||
var loginForm = form();
|
let loginForm = undefined;
|
||||||
|
if (request.filledFields.includes("openid")) {
|
||||||
|
// this is an attempt to focus or submit a form containing only openid field
|
||||||
|
loginForm = form(OPENID_FIELDS);
|
||||||
|
} else {
|
||||||
|
// this is an attempt to focus or submit a regular login form
|
||||||
|
loginForm = form(INPUT_FIELDS);
|
||||||
|
}
|
||||||
|
|
||||||
// ensure the origin is the same or allowed
|
// ensure the origin is the same or allowed
|
||||||
if (window.location.origin !== request.origin) {
|
if (window.location.origin !== request.origin) {
|
||||||
@@ -176,13 +200,11 @@
|
|||||||
result.needPressEnter = true;
|
result.needPressEnter = true;
|
||||||
}
|
}
|
||||||
// We need to keep focus somewhere within the form, so that Enter hopefully submits the form.
|
// We need to keep focus somewhere within the form, so that Enter hopefully submits the form.
|
||||||
var password = find(PASSWORD_FIELDS, loginForm);
|
for (let selectors of [OPENID_FIELDS, PASSWORD_FIELDS, USERNAME_FIELDS]) {
|
||||||
if (password) {
|
let field = find(selectors, loginForm);
|
||||||
password.focus();
|
if (field) {
|
||||||
} else {
|
field.focus();
|
||||||
var username = find(USERNAME_FIELDS, loginForm);
|
break;
|
||||||
if (username) {
|
|
||||||
username.focus();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,10 +287,11 @@
|
|||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*
|
*
|
||||||
|
* @param array selectors Selectors to use to find the right form
|
||||||
* @return The login form
|
* @return The login form
|
||||||
*/
|
*/
|
||||||
function form() {
|
function form(selectors) {
|
||||||
const elems = queryAllVisible(document, INPUT_FIELDS, undefined);
|
const elems = queryAllVisible(document, selectors, undefined);
|
||||||
const forms = [];
|
const forms = [];
|
||||||
for (let elem of elems) {
|
for (let elem of elems) {
|
||||||
const form = elem.form;
|
const form = elem.form;
|
||||||
|
Reference in New Issue
Block a user