Compare commits

...

3 commits

Author SHA1 Message Date
Sami Vänttinen
b01af22fd1
Fix detecting new password input in form (#2878) 2026-03-01 13:59:23 +02:00
Sami Vänttinen
a087c8dae0
Ignore password buttons on form submit button detection (#2882) 2026-03-01 08:41:53 +02:00
Sami Vänttinen
589b14a7cc
Improve retry on input field detection with Custom Login Fields (#2875) 2026-03-01 08:32:34 +02:00
3 changed files with 25 additions and 7 deletions

View file

@ -104,8 +104,9 @@ kpxcFields.getExistingCombination = function(combination) {
existingCombination.password ??= combination.password;
if (existingCombination.passwordInputs?.length === 0) {
existingCombination.passwordInputs = combination.passwordInputs;
} else {
existingCombination.passwordInputs.push(combination.password);
} else if (combination?.password) {
// If password field is found in the current combination, force assign it to the existing combination
existingCombination.password = combination.password;
}
// Remove username field from combination with certain sites (replaced by password input)
@ -646,6 +647,11 @@ kpxcFields.useCustomLoginFields = async function() {
kpxcTOTPIcons.newIcon(totp, kpxc.databaseState);
}
// No values found
if (!username && !password && !totp && !submitButton && stringFields?.length === 0) {
return [];
}
const combinations = [];
combinations.push({
username: username,

View file

@ -66,6 +66,9 @@ kpxcForm.getFormSubmitButton = function(form) {
return;
}
const hasPasswordClassOrId = (button) => button
&& (button?.classList.value?.toLowerCase()?.includes('password')
|| button?.id?.toLowerCase()?.includes('password'));
const action = kpxc.submitUrl || form.action;
// Check if the site needs a special handling for retrieving the form submit button
@ -88,13 +91,19 @@ kpxcForm.getFormSubmitButton = function(form) {
b => !b.getAttribute('formAction')
);
if (buttons.length > 0) {
return buttons.at(-1);
const lastButton = buttons.at(-1);
// Accept button if it has no indication for password
if (!hasPasswordClassOrId(lastButton)) {
return buttons.at(-1);
}
}
// Try to find similar buttons outside the form which are added via 'form' property
for (const e of form.elements) {
if ((matchesWithNodeName(e, 'BUTTON') && (e.type === 'button' || e.type === 'submit' || e.type === ''))
|| (matchesWithNodeName(e, 'INPUT') && (e.type === 'button' || e.type === 'submit'))) {
const isSubmitButton = matchesWithNodeName(e, 'BUTTON')
&& (e.type === 'button' || e.type === 'submit' || e.type === '');
const isInputButton = matchesWithNodeName(e, 'INPUT') && (e.type === 'button' || e.type === 'submit');
if ((isSubmitButton || isInputButton) && !hasPasswordClassOrId(e)) {
return e;
}
}

View file

@ -361,7 +361,7 @@ kpxc.initCredentialFields = async function() {
// Search all remaining inputs from the page, ignore the previous input fields
const pageInputs = await kpxcFields.getAllPageInputs(formInputs);
if (formInputs.length === 0 && pageInputs.length === 0 && !kpxcFields.isCustomLoginFieldsUsed()) {
if (formInputs.length === 0 && pageInputs.length === 0) {
// Run 'redetect_credentials' manually if no fields are found after a page load
setTimeout(async function() {
if (_called.automaticRedetectCompleted) {
@ -653,7 +653,10 @@ kpxc.retrieveCredentials = async function(force = false) {
}
kpxc.url = document.location.href;
kpxc.submitUrl = kpxc.getFormActionUrl(kpxc.combinations[0]);
// Search for first combination that has username or password input set
const firstCombination = kpxc.combinations?.find((combination) => combination?.username || combination?.password);
kpxc.submitUrl = kpxc.getFormActionUrl(firstCombination);
if (kpxc.settings.autoRetrieveCredentials && kpxc.url && kpxc.submitUrl) {
await kpxc.retrieveCredentialsCallback(