NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name La Banque Postale - No Virtual Keyboard // @namespace org.bouil // @author bouil // @collaborator foudfou // @copyright 2013-2016, https://github.com/bouil/userscripts // @description Remove virtual keyboard and add a classic input text field for the password on La Banque Postale website https://www.labanquepostale.fr/ // @include https://voscomptesenligne.labanquepostale.fr/wsost/OstBrokerWeb/loginform?TAM_OP=login&ERROR_CODE=0x00000000&URL=%2Fvoscomptes%2FcanalXHTML%2Fidentif.ea%3Forigin%3Dparticuliers // @version 0.4.8 // @updateURL https://openuserjs.org/install/bouil/La_Banque_Postale_-_No_Virtual_Keyboard.user.js // @grant GM_info // @grant GM_getMetadata // ==/UserScript== var debug = false; var hashToNumber = {}; // firefox img width = 189 hashToNumber[1499838977] = -1; hashToNumber[370540883] = 0; hashToNumber[-44352046] = 1; hashToNumber[581656633] = 2; hashToNumber[1649454864] = 3; hashToNumber[-1351301404] = 4; hashToNumber[-1575557345] = 5; hashToNumber[1123413039] = 6; hashToNumber[1544770534] = 7; hashToNumber[1544029925] = 8; hashToNumber[-1887694506] = 9; // firefox img width = 252 hashToNumber[1499838977] = -1; hashToNumber[2037140090] = 0; hashToNumber[-1837280483] = 1; hashToNumber[-39504401] = 2; hashToNumber[1403102968] = 3; hashToNumber[702003925] = 4; hashToNumber[-1495191002] = 5; hashToNumber[307386662] = 6; hashToNumber[-88040056] = 7; hashToNumber[1436389033] = 8; hashToNumber[-1860708088] = 9; // chrome img width = 189 hashToNumber[1261568409] = -1; hashToNumber[-737831289] = 0; hashToNumber[-1939970274] = 1; hashToNumber[1633837072] = 2; hashToNumber[-1476820365] = 3; hashToNumber[-1744932522] = 4; hashToNumber[311929800] = 5; hashToNumber[-1780532980] = 6; hashToNumber[1914433817] = 7; hashToNumber[-1580087094] = 8; hashToNumber[-1726714153] = 9; // chrome img width = 252 hashToNumber[1367079729] = -1; hashToNumber[1361177620] = 0; hashToNumber[104477207] = 1; hashToNumber[-721997744] = 2; hashToNumber[1409920244] = 3; hashToNumber[190752219] = 4; hashToNumber[-161292196] = 5; hashToNumber[1024300490] = 6; hashToNumber[113276182] = 7; hashToNumber[-1874617512] = 8; hashToNumber[528407293] = 9; function hashCode(s){ // djb2 return s.split("").reduce(function(a,b){ a=((a<<5)-a)+b.charCodeAt(0); return a&a; // Convert to 32bit integer },0); } function metaData(str) { if ("undefined" !== typeof(GM_info)) { return GM_info.script[str]; } else if ("undefined" !== typeof(GM_getMetadata)) { return GM_getMetadata(str); } else { console.log("GM_ API unsupported"); return "unknown"; } } function image2number(imageDataBase64) { var imageHash = hashCode(imageDataBase64); var number = hashToNumber[imageHash]; return number; } function decodeGrid(grid) { const kGridSize = 4; var separatorWidth = grid.width/((4*15+3)); // cell/separator proportion is 15 if (debug) { console.log("grid width="+grid.width); console.log("separatorWidth="+separatorWidth); } var cellWidth = separatorWidth*15; // chaque case chiffre fait cellWidth px de côté sans la bordure var canvas, ctx, imageData; var n2p = {}; for (var y=0; y<kGridSize; y++) { for (var x=0; x<kGridSize; x++) { canvas = document.createElement("canvas"); canvas.setAttribute("width", cellWidth); canvas.setAttribute("height", cellWidth); canvas.setAttribute("style", "display: inline; border: 1px solid red;"); ctx = canvas.getContext('2d'); ctx.fillStyle = "rgb(255,255,100)"; ctx.fillRect(0, 0, cellWidth, cellWidth); // drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) ctx.drawImage(grid, (cellWidth+separatorWidth)*x, (cellWidth+separatorWidth)*y, cellWidth, cellWidth, 0, 0, cellWidth, cellWidth); // dst imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); // no need to convertColor(imageData) here. see http://userscripts.org/scripts/show/126488 - FreeMobile TinyAuth ctx.putImageData(imageData, 0, 0); var imageDataBase64 = canvas.toDataURL("image/png").replace(/^data:image\/(png|jpg);base64,/, ""); var number = image2number(imageDataBase64); var gridPosition = (y * kGridSize + x); if (debug) { var br = document.createElement("br"); document.body.appendChild(br); document.body.appendChild(canvas); numberElement = document.createElement("span"); numberElement.setAttribute("style", "border-bottom: 1px solid red;"); numberElement.innerHTML = " row=" + y + ";col=" + x + ";imgNumber=" + gridPosition + ";hash=" + hashCode(imageDataBase64) + " = " + number; document.body.appendChild(numberElement); document.body.appendChild(br); } if (number != -1) { n2p[number] = gridPosition; } if (number < -1 || number > 9) { alert("Décodage de la grille échoué " + number); throw new Error("Décodage échoué."); } } } if (debug) { console.log("Number -> Grille ="); console.log(n2p); } for(n=0;n<10;n++){ if (typeof n2p[n] == "undefined"){ alert("Grille non decodee pour le chiffre " + n + ". Essayez de mettre a jour le script."); break; } } return n2p; } /** * replaces the img/map grid with a simple password input. The login input * remains unchanged. */ function customizeUI(grid) { var divBlocMdp = document.getElementById("cvs-bloc-mdp"); var loginInput = document.getElementById("val_cel_identifiant"); loginInput.setAttribute("autocomplete", "on"); var newPasswordInput = document.getElementById("cvs-bloc-mdp-input").cloneNode(true); newPasswordInput.removeAttribute("disabled"); newPasswordInput.setAttribute("type", "password"); newPasswordInput.setAttribute("autocomplete", "on"); newPasswordInput.setAttribute("maxlength","6"); while (divBlocMdp.hasChildNodes()) { divBlocMdp.removeChild(divBlocMdp.lastChild); } divBlocMdp.appendChild(newPasswordInput); var oldSubmit = document.getElementById("valider"); var newSubmit = oldSubmit.cloneNode(true); // listeners not copied! // onclick sendForm() newSubmit.setAttribute("type", "submit"); newSubmit.setAttribute("id", "gm_submit"); newSubmit.removeAttribute("disabled"); newSubmit.removeAttribute("grey"); newSubmit.style.backgroundColor = "#004B9B"; oldSubmit.parentNode.replaceChild(newSubmit, oldSubmit); // add some info about this script var about = document.createElement("div"); var ptmp = document.createElement("h3"); ptmp.innerHTML = metaData("name"); about.appendChild(ptmp); ptmp = document.createElement("p"); ptmp.innerHTML = "Version " + metaData("version"); about.appendChild(ptmp); newSubmit.parentNode.appendChild(about); document.getElementById("val_cel_identifiant").focus(); return {newSubmit: newSubmit, newPasswordInput: newPasswordInput}; } /** * attach the submit handler, that translates the password to a positional * string, and feeds the dedicated hidden field with it. */ function attachSubmitHandler(map, passwordElt) { function createSubmitHandler(form, map, password){ return function (event) { var password = passwordElt.value; var keyboardPass = ""; for(i = 0 ; i < password.length ; i++){ var k = map[password[i]]; if (k < 10) k = "0" + k; keyboardPass = keyboardPass + k; } document.getElementById("cs").value = keyboardPass; // hidden password if (debug) alert("pass="+keyboardPass); else form.submit(); };} var form = document.forms['formAccesCompte']; var submitHandler = createSubmitHandler(form, map, passwordElt.value); form.addEventListener('submit', submitHandler, false); } function imgSrc(str) { return (str.match(/url\([^\)]+\)/gi) || [""])[0].split(/[()'"]+/)[1]; } function main() { var elt = document.getElementById('imageclavier'), style = elt.currentStyle || window.getComputedStyle(elt, false), bg = style.getPropertyValue('background-image'), gridSrc = imgSrc(bg); if (!gridSrc) { alert("Aucune grille d'identification trouvee"); return; } if (debug) { console.log("Grid is"); console.log(gridSrc); } var customizedUI = customizeUI(elt); var image = new Image(); image.onload = function() { var number2GridPositionMap = decodeGrid(this); attachSubmitHandler(number2GridPositionMap, customizedUI.newPasswordInput); }; image.src = gridSrc; } main();