diff --git a/keepassxc-browser/common/sites.js b/keepassxc-browser/common/sites.js index b83f352..ee159d0 100644 --- a/keepassxc-browser/common/sites.js +++ b/keepassxc-browser/common/sites.js @@ -212,6 +212,8 @@ kpxcSites.formSubmitButtonExceptionFound = function(form) { return $('.button[slot=primary-button]'); } else if (form?.action === 'https://auth.openai.com/log-in/password') { return form.querySelector('button[class*=_primary_]'); + } else if (!form && document.location.origin === 'https://www.reddit.com') { + return $('button.login'); } return undefined; diff --git a/keepassxc-browser/content/form.js b/keepassxc-browser/content/form.js index a07d2f5..0207bc7 100644 --- a/keepassxc-browser/content/form.js +++ b/keepassxc-browser/content/form.js @@ -10,7 +10,7 @@ kpxcForm.savedCustomInputs = []; kpxcForm.savedForms = []; kpxcForm.submitTriggered = false; -// Activate the Credential Banner if existing credentials are not found +// Activate the Credential Banner if credentials are found from form submit kpxcForm.activateCredentialBanner = async function(usernameValue, passwordInputs, passwordField) { let passwordValue = ''; // Check if the form has three password fields -> a possible password change form @@ -163,7 +163,7 @@ kpxcForm.initForm = function(form, credentialFields) { form.addEventListener('submit', kpxcForm.onSubmit); const submitButton = kpxcForm.getFormSubmitButton(form); - if (submitButton !== undefined) { + if (submitButton) { submitButton.addEventListener('click', kpxcForm.onSubmit); } } @@ -181,6 +181,15 @@ kpxcForm.initCustomForm = function(combinations) { } }; +// Identifies a submit button from the page outside any form +kpxcForm.initSubmitButtonFromPage = function() { + let submitButton = kpxcSites.formSubmitButtonExceptionFound(); + submitButton ??= $('button[type=submit], button.login'); + if (submitButton) { + submitButton.addEventListener('click', kpxcForm.onSubmit); + } +}; + // Triggers when a custom form has been identified with a specific form submit button kpxcForm.onCustomFormSubmit = async function(e) { if (!e.isTrusted || kpxcForm.savedCustomInputs?.length === 0) { @@ -227,14 +236,25 @@ kpxcForm.onSubmit = async function(e) { form = kpxcForm.savedForms[0].form; } - if (!form) { + // Try choosing inputs from the last combination detected. + // Needed if initSubmitButtonFromPage() has been used. + let usernameField; + let passwordField; + let passwordInputs = []; + if (!form && kpxc.combinations.length > 0) { + usernameField = kpxc.combinations.at(-1)?.username; + passwordField = kpxc.combinations.at(-1)?.password; + passwordInputs = kpxc.combinations.at(-1)?.passwordInputs; + } else { + [ usernameField, passwordField, passwordInputs ] = kpxcForm.getCredentialFieldsFromForm(form); + } + + if (!form && !usernameField && !passwordField) { logDebug('Error: No form found for submit detection.'); kpxcForm.submitTriggered = false; return; } - const [ usernameField, passwordField, passwordInputs ] = kpxcForm.getCredentialFieldsFromForm(form); - // Use the first text field in the form if only username input is missing const usernameValue = await kpxcForm.getUsernameValue(!usernameField && passwordField ? form?.querySelector('input[type=text]') diff --git a/keepassxc-browser/content/keepassxc-browser.js b/keepassxc-browser/content/keepassxc-browser.js index 70ea565..b51d8e8 100755 --- a/keepassxc-browser/content/keepassxc-browser.js +++ b/keepassxc-browser/content/keepassxc-browser.js @@ -321,9 +321,14 @@ kpxc.initCombinations = async function(inputs = []) { for (const c of combinations) { // If no username field is found, handle the single password field as such const field = c.username || c.password; - if (field && c.form) { - // Initialize form-submit for remembering credentials - kpxcForm.initForm(c.form, c); + if (field) { + if (c.form) { + // Initialize form-submit for remembering credentials + kpxcForm.initForm(c.form, c); + } else { + // Try to search a submit button + kpxcForm.initSubmitButtonFromPage(); + } } // Don't allow duplicates