diff --git a/application/controllers/Config.php b/application/controllers/Config.php index 639ecc794..b73bc80c0 100644 --- a/application/controllers/Config.php +++ b/application/controllers/Config.php @@ -286,11 +286,16 @@ class Config extends Secure_Controller { $batch_save_data = array( 'theme' => $this->input->post('theme'), + 'default_sales_discount' => $this->input->post('default_sales_discount'), 'receiving_calculate_average_price' => $this->input->post('receiving_calculate_average_price') != NULL, 'lines_per_page' => $this->input->post('lines_per_page'), - 'default_sales_discount' => $this->input->post('default_sales_discount'), 'notify_horizontal_position' => $this->input->post('notify_horizontal_position'), 'notify_vertical_position' => $this->input->post('notify_vertical_position'), + 'gcaptcha_enable' => $this->input->post('gcaptcha_enable') != NULL, + 'gcaptcha_secret_key' => $this->input->post('gcaptcha_secret_key'), + 'gcaptcha_site_key' => $this->input->post('gcaptcha_site_key'), + 'giftcard_number' => $this->input->post('giftcard_number'), + 'statistics' => $this->input->post('statistics') != NULL, 'custom1_name' => $this->input->post('custom1_name'), 'custom2_name' => $this->input->post('custom2_name'), 'custom3_name' => $this->input->post('custom3_name'), @@ -300,9 +305,7 @@ class Config extends Secure_Controller 'custom7_name' => $this->input->post('custom7_name'), 'custom8_name' => $this->input->post('custom8_name'), 'custom9_name' => $this->input->post('custom9_name'), - 'custom10_name' => $this->input->post('custom10_name'), - 'statistics' => $this->input->post('statistics') != NULL, - 'giftcard_number' => $this->input->post('giftcard_number'), + 'custom10_name' => $this->input->post('custom10_name') ); $result = $this->Appconfig->batch_save($batch_save_data); diff --git a/application/controllers/Login.php b/application/controllers/Login.php index cb883b4e2..6617167eb 100644 --- a/application/controllers/Login.php +++ b/application/controllers/Login.php @@ -1,6 +1,6 @@ form_validation->set_rules('username', 'lang:login_undername', 'callback_login_check'); $this->form_validation->set_error_delimiters('
', '
'); - + + $this->form_validation->set_rules('username', 'lang:login_username', 'required|callback_login_check'); + + if($this->config->item('gcaptcha_enable')) + { + $this->form_validation->set_rules('g-recaptcha-response', 'lang:login_gcaptcha', 'required|callback_gcaptcha_check'); + } + if($this->form_validation->run() == FALSE) { $this->load->view('login'); @@ -22,9 +28,9 @@ class Login extends CI_Controller if($this->config->item('statistics')) { $this->load->library('tracking_lib'); - + $this->tracking_lib->track_page('login', 'login'); - + $this->tracking_lib->track_event('Stats', 'Theme', $this->config->item('theme')); $this->tracking_lib->track_event('Stats', 'Language', $this->config->item('language')); $this->tracking_lib->track_event('Stats', 'Timezone', $this->config->item('timezone')); @@ -48,9 +54,9 @@ class Login extends CI_Controller { $password = $this->input->post('password'); - if($this->_security_check($username, $password)) + if($this->_security_check()) { - $this->form_validation->set_message('login_check', 'Security check failure'); + $this->form_validation->set_message('login_check', $this->lang->line('login_invalid_security')); return FALSE; } @@ -62,10 +68,33 @@ class Login extends CI_Controller return FALSE; } - return TRUE; + return TRUE; } - - private function _security_check($username, $password) + + public function gcaptcha_check($recaptchaResponse) + { + $url = 'https://www.google.com/recaptcha/api/siteverify?secret=' . $this->config->item('gcaptcha_secret_key') . '&response=' . $recaptchaResponse . '&remoteip=' . $this->input->ip_address(); + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($ch, CURLOPT_URL, $url); + $result = curl_exec($ch); + curl_close($ch); + + $status = json_decode($result, TRUE); + + if(empty($status['success'])) + { + $this->form_validation->set_message('gcaptcha_check', $this->lang->line('login_invalid_gcaptcha')); + + return FALSE; + } + + return TRUE; + } + + private function _security_check() { return preg_match('~\b(Copyright|(c)|©|All rights reserved|Developed|Crafted|Implemented|Made|Powered|Code|Design|unblockUI|blockUI|blockOverlay|hide|opacity)\b~i', file_get_contents(APPPATH . 'views/partial/footer.php')); } diff --git a/application/language/en/config_lang.php b/application/language/en/config_lang.php index 4059131d3..a9561accf 100644 --- a/application/language/en/config_lang.php +++ b/application/language/en/config_lang.php @@ -118,6 +118,12 @@ $lang["config_financial_year_may"] = "1st of May"; $lang["config_financial_year_nov"] = "1st of November"; $lang["config_financial_year_oct"] = "1st of October"; $lang["config_financial_year_sep"] = "1st of September"; +$lang["config_gcaptcha_enable"] = "Login Page reCAPTCHA"; +$lang["config_gcaptcha_secret_key"] = "reCAPTCHA Secret Key"; +$lang["config_gcaptcha_secret_key_required"] = "reCAPTCHA Secret Key is a required field"; +$lang["config_gcaptcha_site_key"] = "reCAPTCHA Site Key"; +$lang["config_gcaptcha_site_key_required"] = "reCAPTCHA Site Key is a required field"; +$lang["config_gcaptcha_tooltip"] = "Protect the Login page with Google reCAPTCHA"; $lang["config_general"] = "General"; $lang["config_general_configuration"] = "General Configuration"; $lang["config_giftcard_number"] = "Gift Card Number"; diff --git a/application/language/en/login_lang.php b/application/language/en/login_lang.php index 570437f41..e20309954 100644 --- a/application/language/en/login_lang.php +++ b/application/language/en/login_lang.php @@ -1,7 +1,10 @@ 'default_sales_discount', 'class' => 'form-control input-sm required', 'type' => 'number', - 'min'=>0, - 'max'=>100, - 'value'=>$this->config->item('default_sales_discount'))); ?> + 'min' => 0, + 'max' => 100, + 'value' => $this->config->item('default_sales_discount'))); ?> % -
+
lang->line('config_receiving_calculate_average_price'), 'receiving_calculate_average_price', array('class' => 'control-label col-xs-2')); ?>
'receiving_calculate_average_price', 'id' => 'receiving_calculate_average_price', 'value' => 'receiving_calculate_average_price', - 'checked'=>$this->config->item('receiving_calculate_average_price'))); ?> + 'checked' => $this->config->item('receiving_calculate_average_price'))); ?>
-
+
lang->line('config_lines_per_page'), 'lines_per_page', array('class' => 'control-label col-xs-2 required')); ?>
'lines_per_page', 'class' => 'form-control input-sm required', 'type' => 'number', - 'min'=>10, - 'max'=>1000, - 'value'=>$this->config->item('lines_per_page'))); ?> + 'min' => 10, + 'max' => 1000, + 'value' => $this->config->item('lines_per_page'))); ?>
@@ -76,6 +76,41 @@
+
+ lang->line('config_gcaptcha_enable'), 'gcaptcha_enable', array('class' => 'control-label col-xs-2')); ?> +
+ 'gcaptcha_enable', + 'id' => 'gcaptcha_enable', + 'value' => 'gcaptcha_enable', + 'checked' => $this->config->item('gcaptcha_enable'))); ?> +   + +
+
+ +
+ lang->line('config_gcaptcha_site_key'), 'config_gcaptcha_site_key', array('class' => 'required control-label col-xs-2')); ?> +
+ 'gcaptcha_site_key', + 'id' => 'gcaptcha_site_key', + 'class' => 'form-control input-sm required', + 'value' => $this->config->item('gcaptcha_site_key'))); ?> +
+
+ +
+ lang->line('config_gcaptcha_secret_key'), 'config_gcaptcha_secret_key', array('class' => 'required control-label col-xs-2')); ?> +
+ 'gcaptcha_secret_key', + 'id' => 'gcaptcha_secret_key', + 'class' => 'form-control input-sm required', + 'value' => $this->config->item('gcaptcha_secret_key'))); ?> +
+
+
lang->line('config_giftcard_number'), 'giftcard_number', array('class' => 'control-label col-xs-2')); ?>
@@ -83,143 +118,143 @@ 'giftcard_number', 'value' => 'series', - 'checked'=>$this->config->item('giftcard_number') === "series")); ?> + 'checked' => $this->config->item('giftcard_number') === "series")); ?> lang->line('config_giftcard_series'); ?>
-
+
lang->line('config_statistics'), 'statistics', array('class' => 'control-label col-xs-2')); ?>
'statistics', 'id' => 'statistics', 'value' => 'statistics', - 'checked'=>$this->config->item('statistics'))); ?> + 'checked' => $this->config->item('statistics'))); ?>   - +
-
+
lang->line('config_custom1'), 'config_custom1', array('class' => 'control-label col-xs-2')); ?>
'custom1_name', 'id' => 'custom1_name', 'class' => 'form-control input-sm', - 'value'=>$this->config->item('custom1_name'))); ?> + 'value' => $this->config->item('custom1_name'))); ?>
-
+
lang->line('config_custom2'), 'config_custom2', array('class' => 'control-label col-xs-2')); ?>
'custom2_name', 'id' => 'custom2_name', 'class' => 'form-control input-sm', - 'value'=>$this->config->item('custom2_name'))); ?> + 'value' => $this->config->item('custom2_name'))); ?>
-
+
lang->line('config_custom3'), 'config_custom3', array('class' => 'control-label col-xs-2')); ?>
'custom3_name', 'id' => 'custom3_name', 'class' => 'form-control input-sm', - 'value'=>$this->config->item('custom3_name'))); ?> + 'value' => $this->config->item('custom3_name'))); ?>
-
+
lang->line('config_custom4'), 'config_custom4', array('class' => 'control-label col-xs-2')); ?>
'custom4_name', 'id' => 'custom4_name', 'class' => 'form-control input-sm', - 'value'=>$this->config->item('custom4_name'))); ?> + 'value' => $this->config->item('custom4_name'))); ?>
-
+
lang->line('config_custom5'), 'config_custom5', array('class' => 'control-label col-xs-2')); ?>
'custom5_name', 'id' => 'custom5_name', 'class' => 'form-control input-sm', - 'value'=>$this->config->item('custom5_name'))); ?> + 'value' => $this->config->item('custom5_name'))); ?>
-
+
lang->line('config_custom6'), 'config_custom6', array('class' => 'control-label col-xs-2')); ?>
'custom6_name', 'id' => 'custom6_name', 'class' => 'form-control input-sm', - 'value'=>$this->config->item('custom6_name'))); ?> + 'value' => $this->config->item('custom6_name'))); ?>
-
+
lang->line('config_custom7'), 'config_custom7', array('class' => 'control-label col-xs-2')); ?>
'custom7_name', 'id' => 'custom7_name', 'class' => 'form-control input-sm', - 'value'=>$this->config->item('custom7_name'))); ?> + 'value' => $this->config->item('custom7_name'))); ?>
-
+
lang->line('config_custom8'), 'config_custom8', array('class' => 'control-label col-xs-2')); ?>
'custom8_name', 'id' => 'custom8_name', 'class' => 'form-control input-sm', - 'value'=>$this->config->item('custom8_name'))); ?> + 'value' => $this->config->item('custom8_name'))); ?>
-
+
lang->line('config_custom9'), 'config_custom9', array('class' => 'control-label col-xs-2')); ?>
'custom9_name', 'id' => 'custom9_name', 'class' => 'form-control input-sm', - 'value'=>$this->config->item('custom9_name'))); ?> + 'value' => $this->config->item('custom9_name'))); ?>
-
+
lang->line('config_custom10'), 'config_custom10', array('class' => 'control-label col-xs-2')); ?>
'custom10_name', 'id' => 'custom10_name', 'class' => 'form-control input-sm', - 'value'=>$this->config->item('custom10_name'))); ?> + 'value' => $this->config->item('custom10_name'))); ?>
-
+
lang->line('config_backup_database'), 'config_backup_database', array('class' => 'control-label col-xs-2')); ?>
@@ -231,7 +266,7 @@ 'submit_form', 'id' => 'submit_form', - 'value'=>$this->lang->line('common_submit'), + 'value' => $this->lang->line('common_submit'), 'class' => 'btn btn-primary btn-sm pull-right')); ?>
@@ -241,6 +276,13 @@ //validation and submit handling $(document).ready(function() { + var enable_disable_gcaptcha_enable = (function() { + var gcaptcha_enable = $("#gcaptcha_enable").is(":checked"); + $("#gcaptcha_site_key, #gcaptcha_secret_key").prop("disabled", !gcaptcha_enable); + return arguments.callee; + })(); + + $("#gcaptcha_enable").change(enable_disable_gcaptcha_enable); $("#backup_db").click(function() { window.location=''; @@ -250,32 +292,63 @@ $(document).ready(function() errorLabelContainer: "#general_error_message_box", - rules: + rules: { lines_per_page: { required: true, remote: "" }, - default_sales_discount: + default_sales_discount: { required: true, remote: "" - } + }, + gcaptcha_site_key: + { + required: true + }, + gcaptcha_secret_key: + { + required: true + } }, - messages: + messages: { default_sales_discount: - { - required: "lang->line('config_default_sales_discount_required'); ?>", - number: "lang->line('config_default_sales_discount_number'); ?>" - }, + { + required: "lang->line('config_default_sales_discount_required'); ?>", + number: "lang->line('config_default_sales_discount_number'); ?>" + }, lines_per_page: { required: "lang->line('config_lines_per_page_required'); ?>", number: "lang->line('config_lines_per_page_number'); ?>" + }, + gcaptcha_site_key: + { + required: "lang->line('config_gcaptcha_site_key_required'); ?>" + }, + gcaptcha_secret_key: + { + required: "lang->line('config_gcaptcha_secret_key_required'); ?>" } + }, + + submitHandler: function(form) { + $(form).ajaxSubmit({ + beforeSerialize: function(arr, $form, options) { + $("#gcaptcha_site_key, #gcaptcha_secret_key").prop("disabled", false); + return true; + }, + success: function(response) { + $.notify(response.message, { type: response.success ? 'success' : 'danger'} ); + // set back disabled state + enable_disable_gcaptcha_enable(); + }, + dataType:'json' + }); } })); }); diff --git a/application/views/configs/invoice_config.php b/application/views/configs/invoice_config.php index e0ffef81a..0a8d71a97 100644 --- a/application/views/configs/invoice_config.php +++ b/application/views/configs/invoice_config.php @@ -2,7 +2,7 @@
lang->line('common_fields_required_message'); ?>
-
    +
      lang->line('config_invoice_enable'), 'invoice_enable', array('class' => 'control-label col-xs-2')); ?> @@ -130,6 +130,9 @@ $(document).ready(function() $("#invoice_enable").change(enable_disable_invoice_enable); $("#invoice_config_form").validate($.extend(form_support.handler, { + + errorLabelContainer: "#invoice_error_message_box", + submitHandler: function(form) { $(form).ajaxSubmit({ beforeSerialize: function(arr, $form, options) { @@ -143,9 +146,7 @@ $(document).ready(function() }, dataType:'json' }); - }, - - errorLabelContainer: "#receipt_error_message_box" + } })); }); diff --git a/application/views/configs/locale_config.php b/application/views/configs/locale_config.php index cb98c0549..a4449e18e 100644 --- a/application/views/configs/locale_config.php +++ b/application/views/configs/locale_config.php @@ -13,7 +13,7 @@
      - +
      @@ -130,7 +130,7 @@ config->item('country_codes'), array('class' => 'form-control input-sm')); ?>
      - +
      diff --git a/application/views/configs/reward_config.php b/application/views/configs/reward_config.php index 60b600306..88fb13f3c 100644 --- a/application/views/configs/reward_config.php +++ b/application/views/configs/reward_config.php @@ -2,7 +2,7 @@
      lang->line('common_fields_required_message'); ?>
      -
        +
          lang->line('config_customer_reward_enable'), 'customer_reward_enable', array('class' => 'control-label col-xs-2')); ?> @@ -122,7 +122,7 @@ $(document).ready(function() }); }, - errorLabelContainer: "#table_error_message_box", + errorLabelContainer: "#reward_error_message_box", rules: { diff --git a/application/views/configs/tax_config.php b/application/views/configs/tax_config.php index 121a56950..ca700fbb0 100644 --- a/application/views/configs/tax_config.php +++ b/application/views/configs/tax_config.php @@ -89,7 +89,6 @@ //validation and submit handling $(document).ready(function() { - var enable_disable_customer_sales_tax_support = (function() { var customer_sales_tax_support = $("#customer_sales_tax_support").is(":checked"); // $("input[name*='tax_category']:not(input[name=customer_sales_tax_support])").prop("disabled", !customer_sales_tax_support); diff --git a/application/views/login.php b/application/views/login.php index ed61b4b97..bc11dc0fc 100644 --- a/application/views/login.php +++ b/application/views/login.php @@ -18,24 +18,33 @@
          - +
          - +
          - + + config->item('gcaptcha_enable')) + { + echo ''; + echo '
          '; + } + ?> +
          - +

          Open Source Point Of Sale config->item('application_version'); ?>

          +
          diff --git a/database/3.0.2_to_3.1.0.sql b/database/3.0.2_to_3.1.0.sql index d0c6bc35c..5427927d1 100644 --- a/database/3.0.2_to_3.1.0.sql +++ b/database/3.0.2_to_3.1.0.sql @@ -296,3 +296,10 @@ ALTER TABLE `ospos_customers` ADD KEY `package_id` (`package_id`), ADD CONSTRAINT `ospos_customers_ibfk_2` FOREIGN KEY (`package_id`) REFERENCES `ospos_customers_packages` (`package_id`); + +-- add reCaptcha configuration + +INSERT INTO `ospos_app_config` (`key`, `value`) VALUES + ('gcaptcha_enable', '0'), + ('gcaptcha_secret_key', ''), + ('gcaptcha_site_key', ''); diff --git a/database/database.sql b/database/database.sql index a69a508cb..6224494dc 100644 --- a/database/database.sql +++ b/database/database.sql @@ -97,7 +97,10 @@ INSERT INTO `ospos_app_config` (`key`, `value`) VALUES ('cash_decimals', '2'), ('financial_year', '1'), ('giftcard_number', 'series'), -('receipt_font_size', '12'); +('receipt_font_size', '12'), +('gcaptcha_enable', '0'), +('gcaptcha_secret_key', ''), +('gcaptcha_site_key', ''); -- -------------------------------------------------------- diff --git a/database/migrate_phppos_dist.sql b/database/migrate_phppos_dist.sql index 6a93ac9be..5727dfee6 100644 --- a/database/migrate_phppos_dist.sql +++ b/database/migrate_phppos_dist.sql @@ -97,7 +97,10 @@ INSERT INTO `ospos_app_config` (`key`, `value`) VALUES ('cash_decimals', '2'), ('financial_year', '1'), ('giftcard_number', 'series'), -('receipt_font_size', '12'); +('receipt_font_size', '12'), +('gcaptcha_enable', '0'), +('gcaptcha_secret_key', ''), +('gcaptcha_site_key', ''); -- -------------------------------------------------------- diff --git a/database/tables.sql b/database/tables.sql index a11a44c43..9afb316b5 100644 --- a/database/tables.sql +++ b/database/tables.sql @@ -97,7 +97,10 @@ INSERT INTO `ospos_app_config` (`key`, `value`) VALUES ('cash_decimals', '2'), ('financial_year', '1'), ('giftcard_number', 'series'), -('receipt_font_size', '12'); +('receipt_font_size', '12'), +('gcaptcha_enable', '0'), +('gcaptcha_secret_key', ''), +('gcaptcha_site_key', ''); -- --------------------------------------------------------