diff --git a/.gitignore b/.gitignore
index d77d1e2cb0158706bf4c671c3dff414dbdb5e4b8..5a61616fb290520701c3303abe0e4d015c786454 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,29 +1,30 @@
-nbproject
-/config/sshkeys/git@gitlab.iml.unibe.ch.pub
-/config/sshkeys/git@gitlab.iml.unibe.ch
-/config/projects/mmmu-sf2.json
-/config/projects/mmmu-sf2.json.ok
-/config/projects/doccom.json
-/config/projects/imlplayer.json_1.ok
-/config/projects/mmmu-sf2.json_1.ok
-/config/projects/ci.json_1.ok
-/config/projects/doccom.json_1.ok
-/config/projects/ci.json.ok
-/config/projects/imlplayer.json
-/config/projects/imlplayer.json.ok
-/config/projects/doccom.json.ok
-/config/projects/ci.json
-/database/logs.db
-/public_html/deployment/dummy.db
-/public_html/deployment/classes/ramdb.class.php
-/public_html/~cache/
-/public_html/deployment/classes/spooler-handler.class.php
-/public_html/deployment/pages/act_jstest.php
-/public_html/deployment/classes/html-adminltetest.tpl.php
-/public_html/deployment/adminlte/
-/config/inc_user2projects.php
-/shellscripts/spooler/
-/public_html/valuestore/data/versioncache.db
-/public_html/vendor/medoo/
-/config/_inc_projects_config.php
-/config/inc_projects_config.php
\ No newline at end of file
+nbproject
+/config/sshkeys/git@gitlab.iml.unibe.ch.pub
+/config/sshkeys/git@gitlab.iml.unibe.ch
+/config/projects/mmmu-sf2.json
+/config/projects/mmmu-sf2.json.ok
+/config/projects/doccom.json
+/config/projects/imlplayer.json_1.ok
+/config/projects/mmmu-sf2.json_1.ok
+/config/projects/ci.json_1.ok
+/config/projects/doccom.json_1.ok
+/config/projects/ci.json.ok
+/config/projects/imlplayer.json
+/config/projects/imlplayer.json.ok
+/config/projects/doccom.json.ok
+/config/projects/ci.json
+/database/logs.db
+/public_html/deployment/dummy.db
+/public_html/deployment/classes/ramdb.class.php
+/public_html/~cache/
+/public_html/deployment/classes/spooler-handler.class.php
+/public_html/deployment/pages/act_jstest.php
+/public_html/deployment/classes/html-adminltetest.tpl.php
+/public_html/deployment/adminlte/
+/config/inc_user2projects.php
+/shellscripts/spooler/
+/public_html/valuestore/data/versioncache.db
+/public_html/vendor/medoo/
+/config/_inc_projects_config.php
+/config/inc_projects_config.php
+/.vscode/
\ No newline at end of file
diff --git a/public_html/deployment/classes/actionlog.class.php b/public_html/deployment/classes/actionlog.class.php
index c75eac73f4663dc46f1d485e2adbd9ebc88b043a..d8f68372ab950b6ebd9eb6cf6162c9e83882c29d 100644
--- a/public_html/deployment/classes/actionlog.class.php
+++ b/public_html/deployment/classes/actionlog.class.php
@@ -136,13 +136,24 @@ class Actionlog {
         return $oResult;
     }
 
+    /**
+     * helper function to remove chars in a string
+     * @param string  $sVal      user value
+     * @param string  $sOKChars  good chars to keep
+     * @return string
+     */
+    private function _filterAllowedChars($sVal, $sOKChars){
+        return preg_replace('/[^'.$sOKChars. ']/i', '',$sVal);
+    }
+    
     /**
      * get log data
      * @param array $aFilter with the following keys:
      *   'project' - filter by project; will be mixed with where (see next key)
-     *   'where' - where clausel - part behind "WHERE "
-     *   'order' - order clausel - part behind "ORDER BY "; default is "id DESC" (order by newest entries)
-     *   'limit' - limit clausel - part behind "LIMIT "
+     *   'from   ' - time greater equal; time as string i.e. "2020-06-24" or "2020-06-24 11:00:00"
+     *   'to'      - max time (see from)
+     *   'order'   - order clausel - part behind "ORDER BY "; default is "id DESC" (order by newest entries)
+     *   'limit'   - limit clausel - part behind "LIMIT "
      * @return array
      */
     public function getLogs($aFilter = array()) {
@@ -151,22 +162,27 @@ class Actionlog {
 
         $sSql = 'SELECT `id`,`time`,`loglevel`,`ip`,`user`,`project`,`action`,`message`  from logs ';
         $sWhere = false;
-        if (array_key_exists("where", $aFilter) && $aFilter["where"]) {
-            $sWhere.=' WHERE (' . $aFilter["where"] . ') ';
-        }
+        
+        $aWhere=array();
         if (array_key_exists("project", $aFilter) && $aFilter["project"]) {
-            $sProjectWhere = '`project`="' . $aFilter["project"] . '"';
-            $sWhere.= $sWhere ? ' AND ' . $sProjectWhere : 'WHERE ' . $sProjectWhere;
+            $aWhere[]='`project`="' . $this->_filterAllowedChars($aFilter["project"], '[a-z0-9\-\_]') . '"';
+        }
+        if (array_key_exists("from", $aFilter) && $aFilter["from"]) {
+            $aWhere[]='`time`>="' . $this->_filterAllowedChars($aFilter["from"], '[0-9\-\ \:]') . '"';
+        }
+        if (array_key_exists("to", $aFilter) && $aFilter["to"]) {
+            $aWhere[]='`time`<="' . $this->_filterAllowedChars($aFilter["to"], '[0-9\-\ \:]') . '"';
         }
-        $sSql.=$sWhere;
 
+        $sSql.=(count($aWhere) ? 'WHERE '. implode(' AND ', $aWhere) : '');
+        
         if (array_key_exists("order", $aFilter) && $aFilter["order"]) {
-            $sSql.=' ORDER BY ' . $aFilter["order"];
+            $sSql.=' ORDER BY ' . $this->_filterAllowedChars($aFilter["order"], '[a-z\`0-9\,\ ]');
         } else {
             $sSql.=' ORDER BY id DESC ';
         }
         if (array_key_exists("limit", $aFilter) && $aFilter["limit"]) {
-            $sSql.=' LIMIT ' . $aFilter["limit"];
+            $sSql.=' LIMIT ' . $this->_filterAllowedChars($aFilter["limit"], '[0-9\,\ ]');
         }
         
         foreach ($this->_makeQuery($sSql) as $row) {
@@ -205,11 +221,11 @@ class Actionlog {
             ''=>array('label'=>t("all")), 
         );
         $aTimes=array(
-            ">'".date("Y-m-d", date("U"))."'"=>array('label'=>t("class-actionlog-time-today")),
-            ">'".date("Y-m-d", date("U") - 60*60*24*1)."'"=>array('label'=>t("class-actionlog-time-since-yesterday")),
-            ">'".date("Y-m-d", date("U") - 60*60*24*7)."'"=>array('label'=>t("class-actionlog-time-for-1-week")),
-            ">'".date("Y-m-d", date("U") - 60*60*24*7*2)."'"=>array('label'=>sprintf(t("class-actionlog-time-for-n-weeks"), "2")),
-            ">'".date("Y-m-d", date("U") - 60*60*24*7*4)."'"=>array('label'=>sprintf(t("class-actionlog-time-for-n-weeks"), "4")),
+            ">'".date("Y-m-d", date("U"))."'"                =>array('label'=>t("class-actionlog-time-today")),
+            ">'".date("Y-m-d", date("U") - 60*60*24*1)."'"   =>array('label'=>t("class-actionlog-time-since-yesterday")),
+            ">'".date("Y-m-d", date("U") - 60*60*24*7)."'"   =>array('label'=>t("class-actionlog-time-for-1-week")),
+            ">'".date("Y-m-d", date("U") - 60*60*24*7*2)."'" =>array('label'=>sprintf(t("class-actionlog-time-for-n-weeks"), "2")),
+            ">'".date("Y-m-d", date("U") - 60*60*24*7*4)."'" =>array('label'=>sprintf(t("class-actionlog-time-for-n-weeks"), "4")),
             ''=>array('label'=>t("all")), 
         );
         
@@ -250,7 +266,7 @@ class Actionlog {
                     $aForms["filter"]["form"]['selectproject']['options'][$row[0]]=array('label'=>$row[0]);
                 }
             }
-            $aForms["filter"]["form"]['selectWheretime'] = array(
+            $aForms["filter"]["form"]['selectfrom'] = array(
                     'type' => 'select',
                     'name' => 'selectWheretime',
                     'label' => '<i class="glyphicon glyphicon-calendar"></i> '.t("class-actionlog-time"),
diff --git a/public_html/deployment/classes/sws.class.php b/public_html/deployment/classes/sws.class.php
index 433ab7c47eae18fcf53f741415ce1d5b5ce57820..8fcbd7dacfb2eadde41b4674a065662ab2dba340 100644
--- a/public_html/deployment/classes/sws.class.php
+++ b/public_html/deployment/classes/sws.class.php
@@ -174,10 +174,16 @@ class sws {
      */
     private function _verifyParamValue($sParamValue){
         $sOKChars='a-z0-9\"\{\}\[\]\.\,\ \:\-\+';
+        /*
+        $sOKChars='a-z0-9\"\`\'\{\}\[\]\.\,\ \:\-\+'
+        .'\<\>\='
+        ;
+         */
         if(isset($this->_aParams[$sParamValue])){
             $sVal=urldecode($this->_aParams[$sParamValue]);
-            if(preg_match('/[^'.$sOKChars. ']/i', $sVal)){
-                $this->_quit("ERROR: parameter $sParamValue=.. contains unsupported character(s): [". preg_replace('/['.$sOKChars. ']/i', '',$sVal)."]");
+            $sBadchars=preg_replace('/['.$sOKChars. ']/i', '',$sVal);
+            if($sBadchars){
+                $this->_quit("ERROR: parameter $sParamValue=.. contains unsupported character(s): [". $sBadchars."]");
             }
             
         }
diff --git a/public_html/deployment/js/functions.js b/public_html/deployment/js/functions.js
index 87a3db1e183204992d7ea58adf1edcfd5bca24fc..e95d9e44f61f17af2635190275aa45b40af933f7 100644
--- a/public_html/deployment/js/functions.js
+++ b/public_html/deployment/js/functions.js
@@ -60,8 +60,8 @@ $(document).ready(function() {
 /**
  * get filtered action log table
  * @returns {undefined}
- */
-function updateActionlog(){
+
+function __REMOVEME___updateActionlog(){
     var sUrlBase="/webservice/?class=Actionlog&action=getLogs&type=json&args=";
     var aArgs={};
 
@@ -124,7 +124,58 @@ function updateActionlog(){
     });
     
 }
+ */
+
+/**
+ * get filtered action log table
+ * @returns {undefined}
+ */
+function updateActionlog(){
+    var sUrlBase="/webservice/?class=Actionlog&action=getLogs&type=json&args=";
+    
+    // columns in output table
+    var aTableitems=["id", "time", "loglevel", "ip", "user", "project", "action", "message"];
+  
+    var aArgs={
+        'project': $('#selectproject').val(),
+        'from':    $('#selectfrom').val(),
+        'to':      $('#selectto').val(),
+        'limit':   $('#selectlimit').val(),
+    }
+    
+    // --- get data
 
+    var sUrl=sUrlBase+'['+JSON.stringify(aArgs)+']';
+    $.post( sUrl, function( aData ) {
+        var sHtml='';
+        
+        // --- generate output
+        if (aData.length && aData[0]["id"]){
+            for (i=0; i<aData.length; i++){
+                sHtml+='<tr class="tractionlogs loglevel-'+aData[i]["loglevel"]+' '+aData[i]["project"]+'">';
+                for (j=0; j<aTableitems.length; j++){
+                    sHtml+='<td>'+aData[i][aTableitems[j]]+'</td>';
+                }
+                sHtml+='</tr>';
+            }
+        }
+        drawTimeline(aData);
+        
+        if (!sHtml){
+            sHtml=sMsgNolog; // variable is set in actionlog.class.php
+        } else {
+            sHead='';
+            for (j=0; j<aTableitems.length; j++){
+                sHead+='<th>'+aTableitems[j]+'</th>';
+            }
+            sHead='<thead><tr>'+sHead+'</tr></thead>';
+            sHtml='<table class="table table-condensed">'+sHead+'<tbody>'+sHtml+'</tbody></table>';
+        }
+        $('#tableLogactions').html(sHtml);
+        filterLogTable();
+    });
+    
+}
 /**
  * render timeline with Visjs
  *