https://bugs.kde.org/show_bug.cgi?id=475231

            Bug ID: 475231
           Summary: [Patch] Fix form detection for password manager
    Classification: Applications
           Product: Falkon
           Version: 23.08.1
          Platform: Other
                OS: Other
            Status: REPORTED
          Severity: task
          Priority: NOR
         Component: general
          Assignee: now...@gmail.com
          Reporter: baldiniebald...@gmail.com
  Target Milestone: ---

I fixed the form detection script in /src/lib/tools/scripts.cpp used to capture
the login credentials for the password manager. I tested this on many websites,
all work correctly.

This fixes two problems:

1) Some websites collect data from login forms without properly submit()ting
them, thus the 'submit' event handler currently in use does not trigger;

2) the current script collects the DOM forms by reading 'document.forms', but
this property often holds an empty set, and MutationObserver doesn't
subsequently detect further forms. This patch circumvents this issue.

# This patch file was generated by NetBeans IDE
# It uses platform neutral UTF-8 encoding and \n newlines.
--- a/src/lib/tools/scripts.cpp
+++ b/src/lib/tools/scripts.cpp
@@ -74,31 +74,37 @@
 QString Scripts::setupFormObserver()
 {
     QString source = QL1S("(function() {"
-                          "function findUsername(inputs) {"
-                          "    var usernameNames = ['user', 'name', 'login'];"
-                          "    for (var i = 0; i < usernameNames.length; ++i)
{"
-                          "        for (var j = 0; j < inputs.length; ++j)"
-                          "            if (inputs[j].type == 'text' &&
inputs[j].value.length && inputs[j].name.indexOf(usernameNames[i]) != -1)"
-                          "                return inputs[j].value;"
+                          "    let eFormsOld  = [],"
+                          "        eFormsDone = [];"
+                          ""
+                          "    function findUsername(inputs) {"
+                          "        let usernameNames = ['user', 'name',
'login'];"
+                          ""
+                          "        for (let i = 0; i < usernameNames.length;
++i) {"
+                          "            for (let j = 0; j < inputs.length;
++j)"
+                          "                if (inputs[j].type == 'text' &&
inputs[j].value.length && inputs[j].name.indexOf(usernameNames[i]) != -1)"
+                          "                    return inputs[j].value;"
+                          "        }"
+                          ""
+                          "        for (let i = 0; i < inputs.length; ++i)"
+                          "            if (inputs[i].type == 'text' &&
inputs[i].value.length)"
+                          "                return inputs[i].value;"
+                          ""
+                          "        for (let i = 0; i < inputs.length; ++i)"
+                          "            if (inputs[i].type == 'email' &&
inputs[i].value.length)"
+                          "                return inputs[i].value;"
+                          ""
+                          "        return '';"
                           "    }"
-                          "    for (var i = 0; i < inputs.length; ++i)"
-                          "        if (inputs[i].type == 'text' &&
inputs[i].value.length)"
-                          "            return inputs[i].value;"
-                          "    for (var i = 0; i < inputs.length; ++i)"
-                          "        if (inputs[i].type == 'email' &&
inputs[i].value.length)"
-                          "            return inputs[i].value;"
-                          "    return '';"
-                          "}"
                           ""
-                          "function registerForm(form) {"
-                          "    form.addEventListener('submit', function() {"
-                          "        var form = this;"
-                          "        var data = '';"
-                          "        var password = '';"
-                          "        var inputs =
form.getElementsByTagName('input');"
-                          "        for (var i = 0; i < inputs.length; ++i) {"
-                          "            var input = inputs[i];"
-                          "            var type = input.type.toLowerCase();"
+                          "    function processForm(eForm) {"
+                          "        let data = '';"
+                          "        let password = '';"
+                          "        let inputs =
eForm.getElementsByTagName('input');"
+                          ""
+                          "        for (let i = 0; i < inputs.length; ++i) {"
+                          "            let input = inputs[i];"
+                          "            let type = input.type.toLowerCase();"
                           "            if (type != 'text' && type !=
'password' && type != 'email')"
                           "                continue;"
                           "            if (!password && type == 'password')"
@@ -108,30 +114,61 @@
                           "            data +=
encodeURIComponent(input.value);"
                           "            data += '&';"
                           "        }"
+                          ""
                           "        if (!password)"
                           "            return;"
+                          ""
+                          "        if (eFormsDone.every(e => e != eForm)) {"
+                          "            eFormsDone.push(eForm);"
+                          "        } else {"
+                          "            return;"
+                          "        }"
+                          ""
                           "        data = data.substring(0, data.length - 1);"
-                          "        var url = window.location.href;"
-                          "        var username = findUsername(inputs);"
+                          "        let url = window.location.href;"
+                          "        let username = findUsername(inputs);"
                           "        external.autoFill.formSubmitted(url,
username, password, data);"
-                          "    }, true);"
-                          "}"
+                          "    }"
                           ""
-                          "if (!document.documentElement) return;"
+                          "    function undoForm(eForm) {"
+                          "        let i = eFormsDone.indexOf(eForm);"
                           ""
-                          "for (var i = 0; i < document.forms.length; ++i)"
-                          "    registerForm(document.forms[i]);"
+                          "        if (i => 0) {"
+                          "            eFormsDone.splice(i, 1);"
+                          "        }"
+                          "    }"
                           ""
-                          "var observer = new
MutationObserver(function(mutations) {"
-                          "    for (var mutation of mutations)"
-                          "        for (var node of mutation.addedNodes)"
-                          "            if (node.tagName &&
node.tagName.toLowerCase() == 'form')"
-                          "                registerForm(node);"
-                          "});"
-                          "observer.observe(document.documentElement, {
childList: true, subtree: true });"
+                          "    function registerForm(eForm) {"
+                          "        let eInputs =
eForm.getElementsByTagName('input');"
                           ""
+                          "        eForm.addEventListener('submit', () =>
processForm(eForm), true);"
+                          ""
+                          "        for (let eInput of eInputs) {"
+                          "            let type = eInput.type.toLowerCase();"
+                          "            "
+                          "            if (type == 'password') {"
+                          "                eInput.addEventListener('blur', ()
=> processForm(eForm), true);"
+                          "                eInput.addEventListener('input', ()
=> undoForm(eForm), true);"
+                          "                eInput.addEventListener('keydown',
() => event.keyCode === 13 && processForm(eForm), true);"
+                          "            }"
+                          "        }"
+                          "    }"
+                          ""
+                          "    setInterval(() => {"
+                          "        try {"
+                          "            let eFormsNew =
Array.from(document.forms);"
+                          ""
+                          "            for (let eFormNew of eFormsNew) {"
+                          "                if (eFormsOld.every(e => e !=
eFormNew)) {"
+                          "                    eFormsOld.push(eFormNew);"
+                          "                    registerForm(eFormNew);"
+                          "                }"
+                          "            }"
+                          ""
+                          "        } catch (e) {}"
+                          "    }, 100);"
                           "})()");
-
+
     return source;
 }

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to