Commit dfcaba37 authored by Sven Franck's avatar Sven Franck

added default client-side form securing

parent e37a3956
......@@ -285,9 +285,12 @@ html body .ui-btn.flag.ui-icon-flag-en:after {background-position: 0px -18px; }
.ribbon:after {
right: 0;
}
/* ====================== recaptcha =================================== */
/* ====================== recaptcha/form spamhandling=================================== */
/* needed to prevent captcha CSS being overriden by ERP5 td height 34px */
html body div#recaptcha_area table#recaptcha_table th,
html body div#recaptcha_area table#recaptcha_table td {
height: 6px;
}
html body form input.secure_form {
display: none;
}
\ No newline at end of file
......@@ -17,7 +17,8 @@
"class_list": "responsive",
"property_dict": {
"editable": true,
"captcha": "captcha",
"secure": "default",
"secret_hash": "foo",
"public_key": "6Ldpb-oSAAAAAGwriKpk4ol1n4yjN_as6M4xv0zA"
},
"children": [{
......
......@@ -13,11 +13,89 @@
erp5 = {},
// JQM content erateerator
factory = {},
// Shims
shim_dict = {},
// renderJS
javascript_registration_dict = {},
renderJS = {};
/* ====================================================================== */
/* SHIMS */
/* ====================================================================== */
// NOTE: to support IE8+/Windows Mobile where possible, test via modernizr
// https://gist.github.com/yahiko/229984
shim_dict.Base64 = {
characters: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" ,
/**
* Shim for atob (not available on IE8+9+Windows Mobile?)
* @method Base64.encode
* @param {string} string String to be hashed
* @return {string} encoded string
*/
encode: function( string ) {
var characters = shim_dict.Base64.characters;
var result = '';
var i = 0;
do {
var a = string.charCodeAt(i++);
var b = string.charCodeAt(i++);
var c = string.charCodeAt(i++);
a = a ? a : 0;
b = b ? b : 0;
c = c ? c : 0;
var b1 = ( a >> 2 ) & 0x3F;
var b2 = ( ( a & 0x3 ) << 4 ) | ( ( b >> 4 ) & 0xF );
var b3 = ( ( b & 0xF ) << 2 ) | ( ( c >> 6 ) & 0x3 );
var b4 = c & 0x3F;
if( ! b ) {
b3 = b4 = 64;
} else if( ! c ) {
b4 = 64;
}
result += characters.charAt( b1 ) + characters.charAt( b2 ) +
characters.charAt( b3 ) + characters.charAt( b4 );
} while ( i < string.length );
return result;
},
/**
* Shim for btoa (not available on IE8+9+Windows Mobile?)
* @method Base64.decode
* @param {string} string String to be hashed
* @return {string} encoded string
*/
decode: function( string ) {
var characters = shim_dict.Base64.characters;
var result = '';
var i = 0;
do {
var b1 = characters.indexOf( string.charAt(i++) );
var b2 = characters.indexOf( string.charAt(i++) );
var b3 = characters.indexOf( string.charAt(i++) );
var b4 = characters.indexOf( string.charAt(i++) );
var a = ( ( b1 & 0x3F ) << 2 ) | ( ( b2 >> 4 ) & 0x3 );
var b = ( ( b2 & 0xF ) << 4 ) | ( ( b3 >> 2 ) & 0xF );
var c = ( ( b3 & 0x3 ) << 6 ) | ( b4 & 0x3F );
result += String.fromCharCode(a) + (b?String.fromCharCode(b):'') + (c?String.fromCharCode(c):'');
} while( i < string.length );
return result;
}
};
/* ====================================================================== */
/* MAPPING ERP5 */
/* ====================================================================== */
......@@ -1374,6 +1452,7 @@
* @return controlgroup
*/
// TODO: crap to use both layout and children!
// NOTE: securing ? http://nedbatchelder.com/text/stopbots.html
factory.generateForm = function (spec) {
var i,
j,
......@@ -1388,14 +1467,16 @@
doc,
config,
value,
secure = spec.property_dict.captcha,
stamp,
encode,
secure = spec.property_dict.secure,
safety_box,
noscript,
fragment = factory.util.wrapInForm(spec),
wrap = function (area, captcha) {
var keys = {};
// set key so it can be retrieved when binding the form
// set optional captcha config
if (captcha) {
keys.id = spec.id + "_captcha";
keys["data-key"] = spec.property_dict.public_key;
......@@ -1409,7 +1490,7 @@
);
};
// form fields = layout
// loop over form layout sections
for (i = 0; i < spec.layout.length; i += 1) {
layout = spec.layout[i];
area = layout.position === "center" ? 2 : 1;
......@@ -1444,23 +1525,69 @@
true,
position
));
// secure
if (j === 0 && secure === "default") {
stamp = new Date().getTime();
encode = window.atob || shim_dict.Base64.encode;
container.appendChild(factory.generateFormElement(
{
"type": "input",
"direct": {
"type": "text",
"value": "",
"className": "secure_form"
},
"attributes": {"data-enhanced":"true"},
"logic": {
"plain_element": true,
"label":"Please do not fill out this field",
"label_i18n": "global.form_helpers.secure_blank"
}
}
));
container.appendChild(factory.generateElement(
"input",
{
"type":"hidden",
"value":spec.property_dict.secret_hash,
"id": spec.id + "_not_a_secret"
},
{
"data-created": stamp
}
));
container.appendChild(factory.generateFormElement(
{
"type": "input",
"direct": {
"type": "text",
"value": encode(
stamp.toString() + spec.property_dict.secret_hash
),
"className": "secure_form"
},
"attributes": {"data-enhanced":"true"},
"logic": {
"plain_element": true,
"label":"Please leave this value unchanged",
"label_i18n": "global.form_helpers.secure_filled"
}
}
));
}
}
fragment.appendChild(container);
}
// set captcha or anti spam protection
switch (secure) {
case "default":
console.log("secure silently")
break;
case "captcha":
if (spec.property_dict.public_key) {
safety_box = wrap(1, true);
fragment.appendChild(safety_box);
} else {
util.errorHandler({"error": "Captcha - No public key supplied"});
}
break;
if (secure === "captcha") {
if (spec.property_dict.public_key) {
safety_box = wrap(1, true);
fragment.appendChild(safety_box);
} else {
util.errorHandler({"error": "Captcha - No public key supplied"});
}
}
// children (default to 1 or 2? crap!)
......@@ -2646,7 +2773,9 @@
disabled + readonly + (action || "") + (clear || "") + (theme || "");
// container
if (config.type === "textarea" || config.logic.type === "hidden") {
if (config.type === "textarea" ||
config.direct.type === "hidden" ||
config.logic.plain_element) {
container = wrapper;
} else {
wrap_in_container = true;
......@@ -2686,7 +2815,9 @@
// NOTE: for checkboxRadio validation, the label needs to be AFTER
// the input, otherwise CSS sibling selector will not work. This saves
// doing "invalid" handler with javascript
if (need_text_node === undefined && !label_inside) {
if (need_text_node === undefined &&
!label_inside &&
config.logic.plain_element === undefined) {
label_target.appendChild(addLabel(config, label_class_list));
}
......@@ -3896,7 +4027,7 @@
form_element = form_list[j];
captcha = document.getElementById(form_element.id + "_captcha");
// add captcha
// captcha
if (captcha) {
renderJS.declareJS(
"http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"
......
......@@ -20,6 +20,10 @@
"no_items": "No items found",
"back": "Back",
"clear": "Delete"
},
"form_helpers": {
"secure_blank": "Please do not fill out this field",
"secure_filled": "Please leave this value unchanged"
}
},
"pages": {
......
......@@ -20,6 +20,10 @@
"no_items": "无法找到该项目",
"back": "后退",
"clear": "删除"
},
"form_helpers": {
"secure_blank": "Please do not fill out this field",
"secure_filled": "Please leave this value unchanged"
}
},
"pages": {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment