natwest-login

By Nic Ferrier Last update Jul 19, 2005 — Installed 663 times.
// Copyright (C) 2005 by Tapsell-Ferrier Limited
// Released under the GPL license
// http://www.gnu.org/copyleft/gpl.html

// ==UserScript==
// @name          natwest-login
// @namespace     http://www.tapsellferrier.co.uk/downloads
// @description   fill in silly "enter first, twelth and fourth" boxes
// @include       https://www.nwolb.com/*
// ==/UserScript==


/*
  Polemical Explanation

  I absolutely HATE banks because they don't employ me to write their
  web applications.  Bank webapps are the worst I've ever
  used. They're so shoddy. And there's no excuse for it. Banks earn so
  much money from me and everyone else that they're customer service
  experience (especially the web one) ought to be tip top. But they
  seem to employ people completly ignorant of web architecture.

  The way banks SHOULD do authentication is with client certificates
  because they would be practically unspoofable - you could maybe
  spoof the DNS and present a different banking front end to the user
  but to what end?. Without passwords it's not going to do you much
  good.

  Instead they choose to do authentication like this. With multiple
  tokens and other rubbish they have dreamt up themselves. Do they
  actually employ someone who considers themselves an expert to come
  up with this crap?

  Fortunately, hackers can fight back with Greasemonkey.

  This asks for your PIN and password and then puts the characters
  that the page is asking for in the correct boxes.

  Amusingly I was told by the Natwest people that the whole reason for
  this page was to stop programs from watching keypresses. It worked,
  they explained, because computers can't understand the words
  "first", "second" or "fifth".

  Well, this program won't work then.

  As I say, idiots.

  This program is only a first step. I hope that I'll be able to make
  an infrastructure that can apply client certificates to bank
  authentication thus solving the problem premanently.
 */
   


// This is a portable function to ask for a password with javascript.
// The continuation_func is a function taking one argument, the value that
// is in the entry box when the user presses OK.
// The continuation_func is only called when the user presses OK.
function gm_prompter(prompt, continuation_func)
{
  if (prompt == null || continuation_func == null)
    // throw an exception?
    return;

  var div = document.getElementById("gm_promptbox");
  var prompt_label = null;
  var ok_button = null;
  var cancel_button = null;
  var input_data = null;
  if (div != null)
    {
      prompt_label = document.getElementById("gm_promptbox_label");
      ok_button = document.getElementById("gm_promptbox_ok");
      cancel_button = document.getElementById("gm_promptbox_cancel");
      input_data = document.getElementById("gm_entry");
    }
  else
    {
      div = document.createElement("div");
      div.id = "gm_promptbox";
      // Set up the form
      div.style.display = "none";
      div.style.position = "fixed";
      div.style.height = "100";
      div.style.width = "400";
      div.style.top = (document.height / 2) - 50;
      div.style.left = (document.width / 2) - 200;
      div.style.textAlign = "center";
      div.style.border = "solid";
      var input_form = div.appendChild(document.createElement("form"));
      var p_label = div.appendChild(document.createElement("label"));
      prompt_label = p_label.appendChild(document.createElement("span"));
      prompt_label.id = "gm_promptbox_label";
      prompt_label.textContent = prompt + ": ";
      input_data = p_label.appendChild(document.createElement("input"));
      input_data.id = "gm_entry";
      input_data.type = "password";
      input_data.accesskey = "P";
      ok_button = p_label.appendChild(document.createElement("button"));
      ok_button.id = "gm_promptbox_ok";
      ok_button.type ="button";
      ok_button.textContent = "OK";
      cancel_button = p_label.appendChild(document.createElement("button"));
      cancel_button.id = "gm_promptbox_cancel";
      cancel_button.type = "button";
      cancel_button.textContent = "Cancel";
      
      // Add it to the document
      document.body.appendChild(div);
    }

  // Set the prompt
  prompt_label.textContent = prompt + ": ";

  // The funcs called by the form
  var ok_handler = function (evt)
    {
      GM_log("gm_prompter OK continuation (" + prompt + ") called");
      div.style.display = "none";
      var value = input_data.value;
      input_data.value = null;
      ok_button.removeEventListener("click", ok_handler, true);
      continuation_func(value);
    };
  ok_button.addEventListener("click", ok_handler, true);

  var cancel_handler = function(evt)
    {
      GM_log("gm_prompter Cancel continuation called");
      input_data.value = null;
      div.style.display="none";
    };
  cancel_button.addEventListener("click", cancel_handler, true);

  // Make it appear
  div.style.display = "block;";
  div.style.background = "#4BBFF9";
}


function nw_picker_v2 ()
{
  var indices = new Array();
  indices["first"] = 1;
  indices["second"] = 2;
  indices["third"] = 3;
  indices["fourth"] = 4;
  indices["fifth"] = 5;
  indices["sixth"] = 6;
  indices["seventh"] = 7;
  indices["eighth"] = 8;
  indices["ninth"] = 9;
  indices["tenth"] = 10;


  function nw_helper(re, data, cont)
  {
    var labels = document.getElementsByTagName("label");
    for (var label_index = 0; label_index < labels.length; label_index++)
      {
        var label = labels.item(label_index);
        var m = re.exec(label.textContent);
        if (m)
          {
            var input = document.getElementsByName(label.getAttribute("for")).item(0);
            // GM_log("the index at: " + m[1] + " will be filled with: " + data[indices[m[1]] - 1]);
            var to_enter = data[indices[m[1]] - 1];
            input.value = to_enter;
          }
      }
    cont();
  }

  // Oh! For a good continuation syntax.
  var pin_re = /Enter the (.*) digit from your PIN/;
  var passwd_re = /Enter the (.*) character from your Password/;

  if (pin_re.exec(document.body.textContent) && passwd_re.exec(document.body.textContent))
    {
      gm_prompter("enter pin",
                  function (pin)
                  { nw_helper(pin_re, pin,
                              function () {gm_prompter("enter password",
                                                       function (passwd)
                                                       { nw_helper(passwd_re, passwd,
                                                                   function ()
                                                                   {
                                                                     document.getElementById("NextButton_button").focus();
                                                                   })})})});
    }
}



// This turns autocomplete off which is useful for some other natwest pages.
if (document.forms)
  {
    if (document.forms.length > 1)
      {
        document.forms[0].setAttribute("autocomplete", "on");
        inputs = document.getElementsByTagName("input");
        for (var i = 0; i < inputs.length; i++)
          if (inputs[i].type == "text")
            inputs[i].setAttribute("autocomplete", "on");
      }
  }

// Make it all happen.
window.addEventListener("load", nw_picker_v2, true);

// End