Implemented customizable authentication timeout.
authorJanusz Dobrowolski <janusz@frontaccounting.eu>
Sun, 23 Aug 2009 21:06:10 +0000 (21:06 +0000)
committerJanusz Dobrowolski <janusz@frontaccounting.eu>
Sun, 23 Aug 2009 21:06:10 +0000 (21:06 +0000)
access/login.php
access/timeout.php [new file with mode: 0644]
admin/company_preferences.php
admin/db/company_db.inc
includes/current_user.inc
includes/session.inc
includes/ui/ui_input.inc
sql/alter2.2.php
sql/alter2.2.sql
sql/en_US-demo.sql
sql/en_US-new.sql

index faad080674377ff23ac94b23b57aca59fe95c1cb..7d4389f68f858f826b1bfe1816b1ad1b57ea2f6f 100644 (file)
@@ -12,7 +12,6 @@
        if (!isset($path_to_root) || isset($_GET['path_to_root']) || isset($_POST['path_to_root']))
                die(_("Restricted access"));
        include_once($path_to_root . "/includes/ui/ui_view.inc");
-
        // Display demo user name and password within login form if "$allow_demo_mode" is true
        if ($allow_demo_mode == true)
        {
        if (!isset($def_coy))
                $def_coy = 0;
        $def_theme = $path_to_root . '/themes/default';
-?>
-<html>
-<head>
-<?php echo '<script>'.get_js_png_fix().'</script>'; ?>
+
+$ajax_timeout = strstr($_SERVER['PHP_SELF'], 'timeout.php');
+
+       echo "<html>
+               <head>";
+if (!$ajax_timeout) { // page header
+       echo '<script>'.get_js_png_fix().'</script>'; ?>
 <script type="text/javascript">
 function defaultCompany()
 {
-       document.forms[0].company_login_name.options[<?php echo $def_coy; ?>].selected = true;
+       document.forms[0].company_login_name.options[<?php
+//      echo $def_coy; 
+       echo $_SESSION["wa_current_user"]->company;
+        ?>].selected = true;
        document.getElementById('ui_mode').value = 1;
 }
 </script>
@@ -41,40 +46,53 @@ function defaultCompany()
     <link rel="stylesheet" href="<?php echo $def_theme;?>/login.css" type="text/css" />
 </head>
 
-<body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" onload="defaultCompany()">
+ <body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" onload="defaultCompany()">
+<?php
+} else { // end page header
+?>
+    <title><?php echo 'Timeout'?></title>
+    <meta http-equiv="Content-type" content="text/html; charset=<?php echo $_SESSION['language']->encoding;?>" />
+    <link rel="stylesheet" href="<?php echo $def_theme;?>/login.css" type="text/css" />
+<?php
+};?>
     <table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0">
-        <tr>
+<?php
+if (!$ajax_timeout) { // FA logo
+?>        <tr>
             <td align="center" valign="bottom"><a target="_blank" href="<?php $power_url; ?>"><img src="<?php echo $def_theme;?>/images/logo_frontaccounting.png" alt="FrontAccounting" width="250" height="50" onload="fixPNG(this)" border="0" /></a></td>
                </tr>
+<?php }; ?>
 
         <tr>
             <td align="center" valign="top">
 
                    <table border="0" cellpadding="0" cellspacing="0">
-                       <tr><td colspan=2 align="center"><font size=4><b><?php echo _("Version") . " " . $version . "   Build " . $build_version ?></b></font><br><br></td></tr>
+<?php
+if (!$ajax_timeout) { // FA version info
+?>                     <tr><td colspan=2 align="center"><font size=4><b><?php echo _("Version") . " " . $version . "   Build " . $build_version ?></b></font><br><br></td></tr>
+<?php
+}; // end of FA version info
+?>
                        <tr>
                            <td colspan="2" rowspan="2">
+                                       <form action="<?php 
+                                               echo $ajax_timeout ? $_SERVER['PHP_SELF'] : $_SESSION['timeout']['uri'];
+                                       ?>" name="loginform" method="post">
                     <table width="346" border="0" cellpadding="0" cellspacing="0">
-                                       <form action="<?php echo $_SERVER['PHP_SELF'];?>" name="loginform" method="post">
                                                <input type="hidden" id=ui_mode name="ui_mode" value="0">
                         <tr>
                             <td colspan="5" bgcolor="#FFFFFF"><img src="<?php echo $def_theme; ?>/images/spacer.png" width="346" height="1" alt="" /></td>
-
                                                </tr>
-
                         <tr>
-
-
-
                             <td bgcolor="#367CB5"><img src="<?php echo $def_theme; ?>/images/spacer.png" width="12" height="200" alt="" /></td>
 
                             <!--<td background="<?php echo $def_theme; ?>/images/outline/bg.png" width="233" height="200" colspan="3" valign="top">-->
                             <td class="login" colspan="3" valign="top">
                                 <table border="0" cellpadding="3" cellspacing="0" width="100%">
                                     <tr>
-                                        <td align="right">
-                                        <!--<span class="loginText">Client login<input name="external_login" type="checkbox" value="1" class="loginText"></span>-->
-                                        <br /></td>
+                                                               <td  align ='right'>
+                                    <!--<span class="loginText">Client login<input name="external_login" type="checkbox" value="1" class="loginText"></span>-->
+                                                               <br /></td>
                                     </tr>
 
                                     <tr>
@@ -83,19 +101,26 @@ function defaultCompany()
                                          <span><?php echo _("Password"); ?>:</span><br />
                                          <input type="password" name="password"  value="<?php echo $allow_demo_mode ? "password":""; ?>">
                                          <br />
-                                                                                       <span><?php echo _("Company"); ?>:</span><br />
-                                                                                       <!--<select name="company_login_name" onchange="setCookie()">-->
-                                                                                       <select name="company_login_name">
 <?php
-for ($i = 0; $i < count($db_connections); $i++)
-{
-       echo "<option value=$i>" . $db_connections[$i]["name"] . "</option>";
-}
+       if ($ajax_timeout) {
+               echo "<input type = 'hidden'  name='company_login_name' value='".
+               $_SESSION["wa_current_user"]->company."'>";
+               set_focus('user_name_entry_field');
+       } else {
 ?>
-                                                                                       </select>
-                                                                               <br /><br />
-                                         <?php echo $demo_text;?>
-                                        </td>
+                       <span><?php echo _("Company"); ?>:</span><br />
+                       <!--<select name="company_login_name" onchange="setCookie()">-->
+                       <select name="company_login_name">
+<?php
+                       for ($i = 0; $i < count($db_connections); $i++)
+                               echo "<option value=$i>" . $db_connections[$i]["name"] . "</option>";
+?>
+                       </select>
+                       <br /><br />
+            <?php echo $demo_text;?>
+<?php
+}; // else in_ajax
+?>                                        </td>
                                     </tr>
 
                                     <tr>
@@ -104,11 +129,21 @@ for ($i = 0; $i < count($db_connections); $i++)
                                 </table>
                                </td>
                         </tr>
-                        <tr>
-                            <td colspan="5" bgcolor="#FFFFFF"><img src="<?php echo $def_theme; ?>/images/spacer.png" width="346" height="1" alt="" /></td>
-                        </tr>
-                                               </form>
+<?php
+ if (!$ajax_timeout) 
+       echo "<tr>
+ <td colspan='5' bgcolor='#FFFFFF'><img src='$def_theme/images/spacer.png' width='346' height='1' alt='' /></td>
+         </tr>";
+
+       foreach($_SESSION['timeout']['post'] as $p => $val) {
+               // add all request variables to be resend together with login data
+               if (!in_array($p, array('ui_mode', 'user_name_entry_field', 
+                       'password', 'SubmitUser', 'company_login_name'))) 
+                       echo "<input type='hidden' name='$p' value='$val'>";
+       }
+?>
                     </table>
+                                       </form>
                            </td>
                            <!--<td background="<?php echo $def_theme; ?>/images/outline/r.png" colspan="3" align="right" valign="top"><img src="<?php echo $def_theme; ?>/images/outline/tr.png" width="10" height="10" alt="" /></td>-->
                        </tr>
@@ -120,20 +155,25 @@ for ($i = 0; $i < count($db_connections); $i++)
                            <!--<td background="<?php echo $def_theme; ?>/images/outline/bm.png"><img src="<?php echo $def_theme; ?>/images/outline/bm.png" width="10" height="10" alt=""></td>-->
                            <!--<td><img src="<?php echo $def_theme; ?>/images/outline/br.png" width="10" height="10" alt="" /></td>-->
                        </tr>
-<tr><td>&nbsp;</td></tr><tr>
+<tr><td>&nbsp;</td></tr>
+<?php
+if (!$ajax_timeout) {
+?>
+<tr>
                <td align="center" class="footer"><font size=1><a target='_blank' style="text-decoration: none" HREF='<?php echo $power_url; ?>'><font color="#FFFF00" valign="top">&nbsp;&nbsp;<?php echo $power_by; ?></font></a></font></td>
        </tr>
 <!--<tr><td>&nbsp;</td></tr><tr>
        <td align="center" class="footer"><a target="_blank" HREF="http://frontaccounting.com/"><img src="<?php echo $def_theme; ?>/images/logo_frontaccounting.png"  height="60" width="60" border="0"/></a></td>
 </tr>-->
 <?php
-if ($allow_demo_mode == true)
-{
+ if ($allow_demo_mode == true)
+ {
     ?>
       <tr>
         <!--<td><br><div align="center"><a href="http://frontaccounting.com"><img src="<?php echo $def_theme; ?>/images/logo_frontaccounting.png"  border="0" align="middle" /></a></div></td>-->
       </tr>
     <?php
+ }
 }
 ?>
                    </table>
diff --git a/access/timeout.php b/access/timeout.php
new file mode 100644 (file)
index 0000000..61e28a0
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+/**********************************************************************
+    Copyright (C) FrontAccounting, LLC.
+       Released under the terms of the GNU General Public License, GPL, 
+       as published by the Free Software Foundation, either version 3 
+       of the License, or (at your option) any later version.
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+    See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
+***********************************************************************/
+/*
+       User authentication page popped up after login timeout during ajax call.
+*/
+$path_to_root = '..';
+$page_security = 1;
+include_once($path_to_root . "/includes/session.inc");
+
+include($path_to_root .'/access/login.php');
+
+if (get_post('SubmitUser') && $_SESSION['wa_current_user']->logged_in()) {
+       // After successfull login repeat last ajax call.
+       // Login form consists all post variables from last ajax call.
+echo "<script>
+       var o = opener;
+       if (o) {
+               o.JsHttpRequest.request(document.getElementsByName('SubmitUser')[0], o.document.forms[0]);
+               close();
+       }
+</script>";
+}
+?>
index 3bd7d05e85487bc9d365697e93d3347d1d1dc351..74b878e20dea8bd44b5b7f0d4566ed5db627884d 100644 (file)
@@ -26,6 +26,12 @@ if (isset($_POST['update']) && $_POST['update'] != "")
 
        $input_error = 0;
 
+       if (!check_num('login_tout', 10))
+       {
+               display_error(_("Login timeout must be positive number not less than 10."));
+               set_focus('login_tout');
+               $input_error = 1;
+       }
        if (strlen($_POST['coy_name'])==0)
        {
                $input_error = 1;
@@ -104,8 +110,10 @@ if (isset($_POST['update']) && $_POST['update'] != "")
                        $_POST['email'], $_POST['coy_logo'], $_POST['domicile'],
                        $_POST['use_dimension'], $_POST['curr_default'], $_POST['f_year'], 
                        check_value('no_item_list'), check_value('no_customer_list'), 
-                       check_value('no_supplier_list'), $_POST['base_sales'], check_value('time_zone'), $_POST['add_pct'], $_POST['round_to']);
-
+                       check_value('no_supplier_list'), $_POST['base_sales'], 
+                       check_value('time_zone'), $_POST['add_pct'], $_POST['round_to'],
+                       $_POST['login_tout']);
+               $_SESSION['wa_current_user']->timeout = $_POST['login_tout'];
                display_notification_centered(_("Company setup has been updated."));
        }
        set_focus('coy_name');
@@ -139,6 +147,7 @@ $_POST['f_year']  = $myrow["f_year"];
 $_POST['time_zone']  = $myrow["time_zone"];
 $_POST['version_id']  = $myrow["version_id"];
 $_POST['add_pct'] = $myrow['add_pct'];
+$_POST['login_tout'] = $myrow['login_tout'];
 if ($_POST['add_pct'] == -1)
        $_POST['add_pct'] = "";
 $_POST['round_to'] = $myrow['round_to'];       
@@ -183,6 +192,7 @@ check_row(_("Search Customer List"), 'no_customer_list', null);
 check_row(_("Search Supplier List"), 'no_supplier_list', null);
 label_row("", "&nbsp;");
 check_row(_("Time Zone on Reports"), 'time_zone', $_POST['time_zone']);
+text_row_ex(_("Login Timeout:"), 'login_tout', 10, 10, '', null, null, _('seconds'));
 label_row(_("Version Id"), $_POST['version_id']);
 
 end_outer_table(1);
index ed2b18f1356ae1653d1e319a7bf21d89160bbc04..6baa143da9eaae9090bf051f8fa9940752415393 100644 (file)
@@ -66,7 +66,7 @@ function update_company_gl_setup($retained_act, $profit_loss_act, $debtors_act,
 function update_company_setup($coy_name, $coy_no, $gst_no, $tax_prd, $tax_last, 
        $postal_address, $phone, $fax, $email, $coy_logo, $domicile, $Dimension, 
        $curr_default, $f_year, $no_item_list, $no_customer_list, $no_supplier_list, 
-       $base_sales, $time_zone, $add_pct, $round_to)
+       $base_sales, $time_zone, $add_pct, $round_to, $login_tout)
 {
        if ($f_year == null)
                $f_year = 0;
@@ -89,7 +89,8 @@ function update_company_setup($coy_name, $coy_no, $gst_no, $tax_prd, $tax_last,
                base_sales=$base_sales,
                time_zone=$time_zone,
                add_pct=$add_pct,
-               round_to=$round_to
+               round_to=$round_to,
+               login_tout = ".db_escape($login_tout)."
                WHERE coy_code=1";
 
        db_query($sql, "The company setup could not be updated ");
index 53e7855cdc931db5ccd15d2734719c5b24a8626c..ee9e38f05c06c54718af2d653707c52c03396ffa 100644 (file)
@@ -22,6 +22,8 @@ class current_user
        var $company;
        var $pos;
        var $access;
+       var $timeout;
+       var $last_act;
 
        var $logged;
        var $ui_mode = 0;
@@ -30,7 +32,10 @@ class current_user
 
        function current_user()
        {
-               $this->loginname = $this->username = $this->name = $this->company = "";
+               global $def_coy;
+               
+               $this->loginname = $this->username = $this->name = "";
+               $this->company = isset($def_coy)? $def_coy : 0;
                $this->logged = false;
 
                $this->prefs = new user_prefs();
@@ -66,6 +71,8 @@ class current_user
                    $this->user = @$myrow["id"];
                        update_user_visitdate($this->username);
                        $this->logged = true;
+                               $this->last_act = time();
+                               $this->timeout = session_timeout();
                        }
                }
 
@@ -147,6 +154,7 @@ function price_format($number) {
     return number_format2($number,
        $_SESSION["wa_current_user"]->prefs->price_dec());
 }
+
 // 2008-06-15. Added extra parameter $stock_id and reference for $dec
 //--------------------------------------------------------------------
 function qty_format($number, $stock_id=null, &$dec) {
@@ -337,4 +345,8 @@ function add_user_js_data() {
 
 //--------------------------------------------------------------------------
 
+function session_timeout()
+{
+       return get_company_pref('login_tout');
+}
 ?>
\ No newline at end of file
index e327b3bbe96a0430d2bf9472e33e5dc9b64cf759..dad1c1c94f1cca20259e8f77ac2f937a8e7a18da 100644 (file)
@@ -92,6 +92,20 @@ function strip_quotes($data)
        return $data;
 }
 
+//============================================================================
+//
+//
+function login_timeout()
+{
+       if ($_SESSION["wa_current_user"]->logged) {
+               $tout = $_SESSION["wa_current_user"]->timeout;
+               if ($tout && (time() > $_SESSION["wa_current_user"]->last_act + $tout))
+               {
+                       $_SESSION["wa_current_user"]->logged = false;
+               }
+               $_SESSION["wa_current_user"]->last_act = time();
+       }
+}
 //============================================================================
 if (!isset($path_to_root))
 {
@@ -110,9 +124,13 @@ include_once($path_to_root . "/includes/ajax.inc");
 include_once($path_to_root . "/includes/ui/ui_msgs.inc");
 
 /*
+       Uncomment the setting below when using FA on shared hosting
+       to avoid unexpeced session timeouts.
        Make sure this directory exists and is writable!
-//     $session_save_path = dirname(__FILE__).'/../tmp/';
 */
+//ini_set('session.save_path', dirname(__FILE__).'/../tmp/');
+
+ini_set('session.gc_maxlifetime', 36000); // 10hrs
 
 session_name('FrontAccounting');
 session_start();
@@ -157,15 +175,27 @@ set_error_handler('error_handler' /*, errtypes */);
 
 if (!isset($_SESSION["wa_current_user"]))
        $_SESSION["wa_current_user"] = new current_user();
+
 set_global_connection();
 
+login_timeout();
+
 if (!$_SESSION["wa_current_user"]->logged_in())
 {
        // Show login screen
        if (!isset($_POST["user_name_entry_field"]) or $_POST["user_name_entry_field"] == "")
        {
-               include($path_to_root . "/access/login.php");
-               $Ajax->redirect($path_to_root . "/access/login.php");
+               if (strstr($_SERVER['PHP_SELF'], 'timeout.php') == false) 
+                       $_SESSION['timeout'] = array( 'uri'=> $_SERVER['REQUEST_URI'],
+                               'post' => $_POST);
+
+               if (!in_ajax()) {
+                       include($path_to_root . "/access/login.php");
+               } else {
+                       // ajax update of current page elements - open login window in popup
+                       // to not interfere with ajaxified page.
+                       $Ajax->popup($path_to_root . "/access/timeout.php");
+               }
                exit;
        } else {
                $succeed = $_SESSION["wa_current_user"]->login($_POST["company_login_name"],
index 483a885115df40f7edf9998049ebda9c9937ee27..2ae54e80aa82db5ee29d987e4b2853d782ce2aed 100644 (file)
@@ -394,6 +394,16 @@ function amount_cell($label, $bold=false, $params="", $id=null)
                label_cell(price_format($label), "nowrap align=right ".$params, $id);
 }
 
+//JAM  Allow entered unit prices to be fractional
+function unit_amount_cell($label, $bold=false, $params="", $id=null)
+{
+       if ($bold)
+               label_cell("<b>".unit_price_format($label)."</b>", "nowrap align=right ".$params, $id);
+       else
+               label_cell(unit_price_format($label), "nowrap align=right ".$params, $id);
+}
+
+
 function percent_cell($label, $bold=false, $id=null)
 {
        if ($bold)
@@ -675,6 +685,15 @@ function amount_cells($label, $name, $init=null, $params=null, $post_label=null,
        amount_cells_ex($label, $name, 15, 15, $init, $params, $post_label, $dec);
 }
 
+//JAM  Allow entered unit prices to be fractional
+function unit_amount_cells($label, $name, $init=null, $params=null, $post_label=null, $dec=null)
+{
+       if (!isset($dec))
+               $dec = user_price_dec()+2;
+
+       amount_cells_ex($label, $name, 15, 15, $init, $params, $post_label, $dec+2);
+}
+
 function amount_row($label, $name, $init=null, $params=null, $post_label=null, $dec=null)
 {
        echo "<tr>";
index 63b479f4c1d35170da1eef86a964ab27e70b391b..9e4eaacb6f412d1bd534f83db9b808f7dad8ce8d 100644 (file)
@@ -94,7 +94,7 @@ class fa2_2 {
        //      Test if patch was applied before.
        //
        function installed($pref) {
-               if (check_table($pref, 'company', 'default_delivery_required')) return false;
+               if (check_table($pref, 'company', 'login_tout')) return false;
                if (check_table($pref, 'stock_category', 'dflt_dim2')) return false;
                if (check_table($pref, 'users', 'sticky_doc_date')) return false;
                if (check_table($pref, 'audit_trail')) return false;
index f8848998eee393db88b8e93470b541bae1cf5a30..49f9fc4d0dcaf7834782c7d5957f36e35e9fecd5 100644 (file)
@@ -92,3 +92,5 @@ CREATE TABLE `0_security_roles` (
   PRIMARY KEY  (`id`),
   UNIQUE KEY `role` (`role`)
 ) TYPE=MyISAM AUTO_INCREMENT=8 AUTO_INCREMENT=8 ;
+
+ALTER TABLE `0_company` ADD COLUMN `login_tout` SMALLINT(6) NOT NULL DEFAULT '600';
index 2f1599483d6e22a84af628d1d420ec1196878359..72d0785c6711eca96a7eb4c56c050f1d2da53d08 100644 (file)
@@ -409,12 +409,13 @@ CREATE TABLE `0_company` (
   `time_zone` tinyint(1) NOT NULL default '0',
   `add_pct` int(5) NOT NULL default '-1',
   `round_to` int(5) NOT NULL default '1',
+  `login_tout` SMALLINT(6) NOT NULL DEFAULT '600',
   PRIMARY KEY  (`coy_code`)
 ) TYPE=MyISAM  ;
 
 ### Data of table `0_company` ###
 
-INSERT INTO `0_company` VALUES ('1', 'Training Co.', '9876543', '123456789', '1', '1', 'Address 1\r\nAddress 2\r\nAddress 3', '(222) 111.222.333', '', 'delta@delta.com', 'logo_frontaccounting.jpg', '', 'USD', '1200', '5060', '2100', '5690', '4450', '9990', '3590', '4430', '4010', '4510', '4500', '1510', '5010', '5040', '4010', '1530', '5000', '0', '10', '10', '1000', '20', '20', '30', '1', '2', '0', '0', '0', '1', '0', '0', '', '1', '2.2', '0', '-1', '1');
+INSERT INTO `0_company` VALUES ('1', 'Training Co.', '9876543', '123456789', '1', '1', 'Address 1\r\nAddress 2\r\nAddress 3', '(222) 111.222.333', '', 'delta@delta.com', 'logo_frontaccounting.jpg', '', 'USD', '1200', '5060', '2100', '5690', '4450', '9990', '3590', '4430', '4010', '4510', '4500', '1510', '5010', '5040', '4010', '1530', '5000', '0', '10', '10', '1000', '20', '20', '30', '1', '2', '0', '0', '0', '1', '0', '0', '', '1', '2.2', '0', '-1', '1', '600');
 
 ### Structure of table `0_credit_status` ###
 
index f2efb70e7c64821152aaeaed6d4bf5e15d69306a..d2266787b1cbb1d5fcf7329832bd18386427c99e 100644 (file)
@@ -392,13 +392,14 @@ CREATE TABLE `0_company` (
   `time_zone` tinyint(1) NOT NULL default '0',
   `add_pct` int(5) NOT NULL default '-1',
   `round_to` int(5) NOT NULL default '1',
+  `login_tout` SMALLINT(6) NOT NULL DEFAULT '600',
   PRIMARY KEY  (`coy_code`)
 ) TYPE=MyISAM  ;
 
 
 ### Data of table `0_company` ###
 
-INSERT INTO `0_company` VALUES ('1', 'Company name', '', '', '1', '1', 'N/A', '', '', '', '', '', 'USD', '1200', '5060', '2100', '5690', '4450', '9990', '3590', '4430', '4010', '4510', '4500', '1510', '5010', '5040', '4010', '1530', '5000', '0', '10', '10', '1000', '20', '20', '30', '1', '1', '0', '0', '0', '1', '0', '0', '', '1', '2.2', '0', '-1', '1');
+INSERT INTO `0_company` VALUES ('1', 'Company name', '', '', '1', '1', 'N/A', '', '', '', '', '', 'USD', '1200', '5060', '2100', '5690', '4450', '9990', '3590', '4430', '4010', '4510', '4500', '1510', '5010', '5040', '4010', '1530', '5000', '0', '10', '10', '1000', '20', '20', '30', '1', '1', '0', '0', '0', '1', '0', '0', '', '1', '2.2', '0', '-1', '1', '600');
 
 ### Structure of table `0_credit_status` ###