From 4534805823eede04716ae6f13d6bed3926a3e798 Mon Sep 17 00:00:00 2001
From: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Date: Thu, 16 Mar 2017 23:00:28 -0300
Subject: [PATCH] Bug 18298: Move password generation to template side
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This patch removes a really ugly way to generate a password: the whole
template was sent and parsed to retrieve the "#defaultnewpassfield" node.
To avoid the password to be sent plain text it is certainly better to
generate it client-side.
The same kind of passwords will be generated: 0-9a-zA-Z
The while loop prevents to get an invalid generated password.

Signed-off-by: Marc Véron <veron@veron.ch>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
---
 .../prog/en/modules/members/member-password.tt     | 25 ++++++++++++++++------
 members/member-password.pl                         | 12 -----------
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/member-password.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/member-password.tt
index 5191551c61..4e66075603 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/member-password.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/member-password.tt
@@ -6,14 +6,28 @@
 <script type="text/JavaScript">
 //<![CDATA[
 
+    function generate_password() {
+        // Always generate a strong password
+        var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+        var length = [% minPasswordLength %];
+        var password='';
+        for ( var i = 0 ; i < length ; i++){
+            password += chars.charAt(Math.floor(Math.random()*chars.length));
+        }
+        return password;
+    }
     $(document).ready(function() {
         $("body").on('click', "#fillrandom",function(e) {
             e.preventDefault();
-            $.get("/cgi-bin/koha/members/member-password.pl?member=[% userid %]", function(response) {
-                var defaultnewpass = $(response).find("#defaultnewpassfield").val();
-                $("#newpassword").after("<input type=\"text\" name=\"newpassword\"  id=\"newpassword\" value=\"" + defaultnewpass + "\">").remove();
-                $("#newpassword2").after("<input type=\"text\" name=\"newpassword2\" id=\"newpassword2\" value=\"" + defaultnewpass + "\">").remove();
-            });
+            var password = '';
+            var pattern_regex = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{[% minPasswordLength %],}/;
+            while ( ! pattern_regex.test( password ) ) {
+                password = generate_password();
+            }
+            $("#newpassword").val(password);
+            $("#newpassword").attr('type', 'text');
+            $("#newpassword2").val(password);
+            $("#newpassword2").attr('type', 'text');
         });
         $("div.hint").eq(0).after(" <div class=\"hint\"><a href=\"#\" id=\"fillrandom\">"+_("Click to fill with a randomly generated suggestion. ")+"<strong>"+_("Passwords will be displayed as text")+"</strong>.</a></div>");
 
@@ -120,7 +134,6 @@
 
 </div>
 </div>
-<input type="hidden" name="defaultnewpassfield" id="defaultnewpassfield" value="[% defaultnewpassword %]" />
 <div class="loading hide"><strong>Processing...</strong><img src="[% interface %]/[% theme %]/img/loading.gif" alt="" /></div>
 <div class="yui-b">
 [% INCLUDE 'circ-menu.inc' %]
diff --git a/members/member-password.pl b/members/member-password.pl
index cb922da43c..037828c411 100755
--- a/members/member-password.pl
+++ b/members/member-password.pl
@@ -93,18 +93,6 @@ if ( $newpassword && !scalar(@errors) ) {
         push( @errors, 'BADUSERID' );
     }
 }
-else {
-    my $userid = $bor->{'userid'};
-
-    my $chars              = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
-    my $length             = int( rand(2) ) + C4::Context->preference("minPasswordLength");
-    my $defaultnewpassword = '';
-    for ( my $i = 0 ; $i < $length ; $i++ ) {
-        $defaultnewpassword .= substr( $chars, int( rand( length($chars) ) ), 1 );
-    }
-
-    $template->param( defaultnewpassword => $defaultnewpassword );
-}
 
 if ( $category_type eq 'C') {
     my $patron_categories = Koha::Patron::Categories->search_limited({ category_type => 'A' }, {order_by => ['categorycode']});
-- 
2.14.2