user.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /**
  2. * Part of a framework for a simple user authentication.
  3. */
  4. User = {
  5. /**
  6. * generates a random hex string
  7. */
  8. randomString: function(len)
  9. {
  10. var hex = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
  11. var string = "";
  12. while(len-->0) { string += hex[parseInt(16*Math.random())]; }
  13. return string; },
  14. /**
  15. * marks an input field as invalid/problematic
  16. */
  17. markInvalid: function(input, reason) {
  18. var classes = "";
  19. if(input["class"]) { classes = input.getAttribute("class"); }
  20. input.setAttribute("class", classes + "form-control material errorz");
  21. input.title = reason;
  22. return false; },
  23. /**
  24. * marks an input field as having passed validation
  25. */
  26. markValid: function(input) {
  27. if(input.getAttribute("class")) {
  28. var stripped = input.getAttribute("class").replace("errorz", "");
  29. input.setAttribute("class", stripped); }
  30. input.title = "";
  31. return true; },
  32. /**
  33. * user name validator
  34. */
  35. validName: function(input)
  36. {
  37. var username = input.value;
  38. if(username.trim()=="") { return this.markInvalid(input, "You forgot your user name."); }
  39. if(username.indexOf("'")>-1) { return this.markInvalid(input, "Apostrophes are not allowed in user names."); }
  40. if(username.length<3) { return this.markInvalid(input, "Sorry, user names must be more than 2 letters."); }
  41. return this.markValid(input);
  42. },
  43. /**
  44. * email address validator -- this uses the simplified email validation
  45. * RegExp found on http://www.regular-expressions.info
  46. */
  47. validEmail: function(input)
  48. {
  49. var valid = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/.test(input.value);
  50. if(!valid) { return this.markInvalid(input,"This is not a real email address..."); }
  51. return this.markValid(input);
  52. },
  53. /**
  54. * checks whether the twice typed password is the same
  55. */
  56. passwordMatch: function(input1, input2)
  57. {
  58. var matched = (input1.value==input2.value);
  59. if(!matched) { return this.markInvalid(input2, "The two passwords don't match"); }
  60. return this.markValid(input2);
  61. },
  62. /**
  63. * Checks whether there is a password set
  64. */
  65. validPassword: function(input)
  66. {
  67. var password = input.value;
  68. if(password.trim()=="") { return this.markInvalid(input, "You need to fill in a password"); }
  69. return this.markValid(input);
  70. },
  71. /**
  72. * Checks whether the password is strong enough.
  73. */
  74. strongPassword: function(input)
  75. {
  76. var password = input.value;
  77. if(!this.validPassword(input)) { return false; }
  78. // you want to mofidy the following line to suit your personal preference in
  79. // secure passwords. And remember that any policy you set has to work in an
  80. // international setting. Passwords can contain any Unicode character, and
  81. // are case sensitive. Don't rely on space-separated words, because several
  82. // big languages don't use spaces. Don't demand "numbers and letters" because
  83. // that just confuses your users. If you want to enforce strong passwords,
  84. // calculate how easy it is to guess the password, and report how quickly
  85. // you can figure out their password so that they pick a better one.
  86. if(password.length<4) { return this.markInvalid(input, "Your password is too easy to guess, please pick something longer. Use an entire sentence. if you like."); }
  87. return this.markValid(input);
  88. },
  89. /**
  90. * Validate all values used for user registration, before submitting the form.
  91. *
  92. * NOTE: while this function does front-end validation, it is possible to bypass
  93. * this function using a javascript console. So, in addition to this client-side
  94. * validation the server will also be performing validation once it receives the data
  95. */
  96. processRegistration: function()
  97. {
  98. var valid = true;
  99. var form = document.getElementById('registration');
  100. valid &= this.validName(form["username"]);
  101. valid &= this.validEmail(form["email"]);
  102. valid &= this.passwordMatch(form["password1"], form["password2"]);
  103. valid &= this.strongPassword(form["password1"]);
  104. if(valid) {
  105. form["sha1"].value = Sha1.hash(form["password1"].value);
  106. form["password1"].value = this.randomString(16);
  107. form["password2"].value = form["password1"].value;
  108. form.submit(); }
  109. },
  110. /**
  111. * Validate all values used for user log in, before submitting the form.
  112. *
  113. * NOTE: while this function does front-end validation, it is possible to bypass
  114. * this function using a javascript console. So, in addition to this client-side
  115. * validation the server will also be performing validation once it receives the data
  116. */
  117. processLogin: function()
  118. {
  119. var valid = true;
  120. var form = document.getElementById('login');
  121. valid &= this.validName(form["username"]);
  122. valid &= this.validPassword(form["password1"]);
  123. if(valid) {
  124. form["password"].value = form["password1"].value;
  125. form["sha1"].value = Sha1.hash(form["password1"].value);
  126. // form["password1"].value = this.randomString(16);
  127. form.submit(); }
  128. },
  129. /**
  130. * Validate all values used for email/password updating, before submitting the form.
  131. *
  132. * NOTE: while this function does front-end validation, it is possible to bypass
  133. * this function using a javascript console. So, in addition to this client-side
  134. * validation the server will also be performing validation once it receives the data
  135. */
  136. processUpdate: function()
  137. {
  138. var valid = true;
  139. var update = false;
  140. var form = document.getElementById('update');
  141. // email?
  142. if(form["email"].value.trim()!="") {
  143. valid &= this.validEmail(form["email"]);
  144. if(valid) update = true; }
  145. // password?
  146. if(form["password1"].value.trim()!="") {
  147. valid &= this.passwordMatch(form["password1"], form["password2"]);
  148. valid &= this.strongPassword(form["password1"]);
  149. if(valid) {
  150. form["sha1"].value = Sha1.hash(form["password1"].value);
  151. form["password1"].value = this.randomString(16);
  152. form["password2"].value = form["password1"].value;
  153. update = true; }}
  154. if(valid && update) { form.submit(); }
  155. },
  156. // ------------------------------------------------------------
  157. /**
  158. * A static shorthand function for appendChild
  159. */
  160. add: function(p, c) { p.appendChild(c); },
  161. /**
  162. * A more useful function for creating HTML elements.
  163. */
  164. make: function(tag, properties) {
  165. var tag = document.createElement(tag);
  166. if(properties !== null) {
  167. for(property in properties) {
  168. tag[property] = properties[property]; }}
  169. return tag; },
  170. /**
  171. * Inject a generic login form into the element passed as "parent"
  172. */
  173. injectLogin: function(parent) {
  174. // eliminate the need to type "this." everywhere in the function
  175. var add = this.add;
  176. var make = this.make;
  177. var form = this.make("form", {id: "usered_login_form", action: ".", method: "POST"});
  178. add(form, make("label", {"for": "usered_username", innerHTML: "user name"}));
  179. add(form, make("input", {id: "usered_username", type: "text"}));
  180. add(form, make("label", {"for": "usered_password", innerHTML: "password"}));
  181. add(form, make("input", {id: "usered_password", type: "password"}));
  182. add(form, make("input", {id: "usered_login_button", type: "submit", value: "log in"}));
  183. add(parent, form);
  184. },
  185. /**
  186. * Inject a generic logout form into the element passed as "parent"
  187. */
  188. injectLogout: function(parent) {
  189. // eliminate the need to type "this." everywhere in the function
  190. var add = this.add;
  191. var make = this.make;
  192. var form = make("form", {id: "usered_logout_form", action: ".", method: "POST"});
  193. add(form, make("input", {type: "hidden", name: "op", value: "logout"}));
  194. add(form, make("input", {id: "usered_logout_button", type: "submit", value: "log out"}));
  195. add(parent, form)
  196. }
  197. };