#1458 AutoSubmit WIP

This commit is contained in:
Grzegorz Zając 2023-12-08 13:40:13 +01:00
parent 7cadf2c8dd
commit 861953d26d
12 changed files with 271 additions and 4 deletions

View File

@ -37,7 +37,8 @@ const onMessage = (request, sender) => {
return resolve({
id: sender?.tab?.id,
url: sender?.tab?.url,
urlPath
urlPath,
status: sender?.tab?.status
});
}

View File

@ -20,7 +20,7 @@
import './styles/content_script.scss';
const browser = require('webextension-polyfill');
const { observe, createObserver } = require('./observer');
const { getTabData, getInputs, addInputListener, portSetup, isInFrame } = require('./functions');
const { getTabData, getInputs, addInputListener, portSetup, isInFrame, addFormElementsNumber, getFormElements } = require('./functions');
const contentOnMessage = require('./events/contentOnMessage');
const { loadFromLocalStorage, saveToLocalStorage } = require('../localStorage');
const storeLog = require('../partials/storeLog');
@ -59,6 +59,7 @@ const contentScriptRun = async () => {
}
addInputListener(getInputs(), tabData?.id);
addFormElementsNumber(getFormElements());
const mutationObserver = createObserver(tabData);
observe(mutationObserver);

View File

@ -0,0 +1,38 @@
//
// This file is part of the 2FAS Browser Extension (https://github.com/twofas/2fas-browser-extension)
// Copyright © 2023 Two Factor Authentication Service, Inc.
// Contributed by Grzegorz Zając. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>
//
const addFormElementsNumber = elements => {
let i = 0;
if (!Array.isArray(elements) || elements?.length <= 0) {
return false;
}
elements.map(element => {
if (element?.dataset?.twofasElementNumber) {
return false;
}
element.dataset.twofasElementNumber = i;
i++;
return element;
});
};
module.exports = addFormElementsNumber;

View File

@ -0,0 +1,59 @@
//
// This file is part of the 2FAS Browser Extension (https://github.com/twofas/2fas-browser-extension)
// Copyright © 2023 Two Factor Authentication Service, Inc.
// Contributed by Grzegorz Zając. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>
//
const getFormSubmitElements = require('./getFormSubmitElements');
const closest = (counts, goal) => {
return counts.indexOf(
counts.reduce((prev, curr) => {
return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
})
);
};
const clickSubmit = (inputElement, siteURL) => {
// @TODO: check URL
const inputNumber = parseInt(inputElement?.dataset?.twofasElementNumber || -999);
const submits = getFormSubmitElements();
if (submits.length === 0) {
return false;
} else if (submits.length === 1) {
try {
submits[0].click();
} catch (e) {}
} else {
const submitsNumbers = [];
submits.forEach(submit => {
submitsNumbers.push(parseInt(submit?.dataset?.twofasElementNumber || -999));
});
const submitElement = submits[closest(submitsNumbers, inputNumber)];
if (submitElement) {
try {
submitElement.click();
} catch (e) {}
}
}
};
module.exports = clickSubmit;

View File

@ -0,0 +1,29 @@
//
// This file is part of the 2FAS Browser Extension (https://github.com/twofas/2fas-browser-extension)
// Copyright © 2023 Two Factor Authentication Service, Inc.
// Contributed by Grzegorz Zając. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>
//
const getInputs = require('./getInputs');
const getFormSubmitElements = require('./getFormSubmitElements');
const getFormElements = () => {
const inputs = getInputs();
const formSubmitElements = getFormSubmitElements();
return inputs.concat(formSubmitElements);
};
module.exports = getFormElements;

View File

@ -0,0 +1,34 @@
//
// This file is part of the 2FAS Browser Extension (https://github.com/twofas/2fas-browser-extension)
// Copyright © 2023 Two Factor Authentication Service, Inc.
// Contributed by Grzegorz Zając. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>
//
const getFormSubmitElements = () => {
let submits = Array.from(
document.querySelectorAll(require('../../partials/formSubmitSelectors')())
);
if (submits.length <= 0) {
submits = Array.from(
document.querySelectorAll(require('../../partials/formSubmitSecondSelectors')())
);
}
return submits;
};
module.exports = getFormSubmitElements;

View File

@ -17,8 +17,12 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>
//
exports.addFormElementsNumber = require('./addFormElementsNumber');
exports.addInputListener = require('./addInputListener');
exports.clickSubmit = require('./clickSubmit');
exports.closeNotificationInfo = require('./closeNotificationInfo');
exports.getFormElements = require('./getFormElements');
exports.getFormSubmitElements = require('./getFormSubmitElements');
exports.getInputs = require('./getInputs');
exports.getTabData = require('./getTabData');
exports.getTokenInput = require('./getTokenInput');

View File

@ -19,6 +19,8 @@
/* global Event, KeyboardEvent */
const delay = require('../../partials/delay');
const getTabData = require('./getTabData');
const clickSubmit = require('./clickSubmit');
const inputToken = (request, inputElement, siteURL) => {
return new Promise(resolve => {
@ -69,10 +71,16 @@ const inputToken = (request, inputElement, siteURL) => {
}
return Promise.all(promises)
.then(() => {
.then(async () => {
clearEvent = null;
inputEvent = null;
const tab = await getTabData();
if (tab.status === 'complete') {
clickSubmit(inputElement, siteURL);
}
return resolve({
status: 'completed',
url: siteURL

View File

@ -0,0 +1,46 @@
//
// This file is part of the 2FAS Browser Extension (https://github.com/twofas/2fas-browser-extension)
// Copyright © 2023 Two Factor Authentication Service, Inc.
// Contributed by Grzegorz Zając. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>
//
const formSubmitSecondSelectors = () => {
let buttonSelectors = [
'button#btn-submit'
];
const linkSelectors = [
'a#loginButton.btn.btn-primary'
];
const ignoreButtonSelectors = [
':not([data-role="search-button"])',
':not([data-role="search"])',
':not(#search)'
];
buttonSelectors = buttonSelectors.map(selector => {
return selector + ignoreButtonSelectors.join('');
});
if (linkSelectors.length <= 0) {
return buttonSelectors.join(',');
}
return buttonSelectors.join(',') + ',' + linkSelectors.join(',');
};
module.exports = formSubmitSecondSelectors;

View File

@ -0,0 +1,44 @@
//
// This file is part of the 2FAS Browser Extension (https://github.com/twofas/2fas-browser-extension)
// Copyright © 2023 Two Factor Authentication Service, Inc.
// Contributed by Grzegorz Zając. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>
//
const formSubmitSelectors = () => {
let buttonSelectors = [
'button[type="submit"]'
];
const linkSelectors = [];
const ignoreButtonSelectors = [
':not([data-role="search-button"])',
':not([data-role="search"])',
':not(#search)'
];
buttonSelectors = buttonSelectors.map(selector => {
return selector + ignoreButtonSelectors.join('');
});
if (linkSelectors.length <= 0) {
return buttonSelectors.join(',');
}
return buttonSelectors.join(',') + ',' + linkSelectors.join(',');
};
module.exports = formSubmitSelectors;

View File

@ -20,6 +20,8 @@
exports.delay = require('./delay');
exports.extNameUpdate = require('./extNameUpdate');
exports.extPageOnMessage = require('./extPageOnMessage');
exports.formSubmitSelectors = require('./formSubmitSelectors');
exports.formSubmitSecondSelectors = require('./formSubmitSecondSelectors');
exports.handleTargetBlank = require('./handleTargetBlank');
exports.hidePreloader = require('./hidePreloader');
exports.inputsSelectors = require('./inputsSelectors');

View File

@ -91,7 +91,8 @@ const storeLog = async (level, logID = 0, errObj, url = '') => {
(storage?.browserInfo?.browser_name === 'Chrome' && storage?.browserInfo?.browser_version === '107.0.0.0' && logID === 14) ||
(c?.errorInfo?.message.includes('FILE_ERROR_NO_SPACE')) ||
(c?.status === 407) ||
(c?.errorInfo?.message.includes('An unexpected error occurred'))
(c?.errorInfo?.message.includes('An unexpected error occurred')) ||
(c?.errorInfo?.message.includes('Refused to run the JavaScript URL'))
) {
return false;
}