diff --git a/CHANGELOG b/CHANGELOG
index 03e78611e..91da876b4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -290,6 +290,12 @@
- documents can be updated by dragging a file on a document list item
- dragging a folder on a folder list item oder the drag and drop area will
recursively upload the folder hierarchy including all files
+- fix checking if user is owner when sending notifications
+- do not show fast upload area if access on folder is insufficient
+- do not send notification mail 'submitted review/approval' to owner of
+ document, still send it to uploader of version
+- set default language in login form if language selector is turned off
+- do not show full list of notifiers to none admins
--------------------------------------------------------------------------------
Changes in version 5.1.33
diff --git a/inc/inc.ClassDbAuthentication.php b/inc/inc.ClassDbAuthentication.php
index 2d65e8516..0c7eaad4f 100644
--- a/inc/inc.ClassDbAuthentication.php
+++ b/inc/inc.ClassDbAuthentication.php
@@ -47,6 +47,11 @@ class SeedDMS_DbAuthentication extends SeedDMS_Authentication {
if($user = $dms->getUserByLogin($username)) {
$userid = $user->getID();
+ // Check if password matches
+ if (!seed_pass_verify($password, $user->getPwd())) {
+ $user = null;
+ }
+ } elseif(!empty($this->settings->_enableLoginByEmail) && ($user = $dms->getUserByEmail($username))) {
// Check if password matches
if (!seed_pass_verify($password, $user->getPwd())) {
$user = null;
diff --git a/inc/inc.ClassLdapAuthentication.php b/inc/inc.ClassLdapAuthentication.php
index ff4eb17b9..db9ae1449 100644
--- a/inc/inc.ClassLdapAuthentication.php
+++ b/inc/inc.ClassLdapAuthentication.php
@@ -126,14 +126,16 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication {
* look like if searching for that user didn't return a dn.
*/
if (isset($settings->_ldapBaseDN)) {
- $ldapSearchAttribut = "uid=";
+ $ldapSearchAttribut = "uid";
+ /* $tmpDN will only be used as a last resort if searching for the user failed */
$tmpDN = "uid=".$username.",".$settings->_ldapBaseDN;
}
/* Active directory has a different base dn */
if (isset($settings->_ldapType)) {
if ($settings->_ldapType==1) {
- $ldapSearchAttribut = "sAMAccountName=";
+ $ldapSearchAttribut = "sAMAccountName";
+ /* $tmpDN will only be used as a last resort if searching for the user failed */
$tmpDN = $username.'@'.$settings->_ldapAccountDomainName;
// Add the following if authentication with an Active Dir doesn't work
// See https://sourceforge.net/p/seeddms/discussion/general/thread/19c70d8d/
@@ -155,7 +157,21 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication {
} else {
$bind = @ldap_bind($ds);
}
+
$dn = false;
+
+ /* The simplest search is just the username */
+ $ldapsearchterm = $ldapSearchAttribut.'='.$username;
+ /* If login by email is allowed, the search for user name is ored with
+ * the search for the email.
+ */
+ if($settings->_enableLoginByEmail) {
+ $ldapsearchterm = "|(".$ldapsearchterm.")(mail=".$username.")";
+ }
+ /* If a ldap filter is set, it will be anded */
+ if($settings->_ldapFilter) {
+ $ldapsearchterm = "&(".$ldapsearchterm.")".$settings->_ldapFilter;
+ }
/* If bind succeed, then get the dn of the user. If a filter
* is set, it will be used to allow only those users to log in
* matching the filter criteria. Depending on the type of server,
@@ -163,19 +179,32 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication {
* 'sAMAccountName=' or 'uid='. All other filters are ANDed.
* A common filter is '(mail=*)' to ensure a user has an email
* address.
+ * If the previous bind failed, we could try later to bind with
+ * the user's credentials (this was until 6.0.26 and 5.1.33 the case),
+ * but if login by email is allowed, it makes no sense to try it. The
+ * only way to bind is by using a correct dn and that cannot be
+ * formed with an email.
*/
if ($bind) {
+ /*
if (!empty($settings->_ldapFilter)) {
- $search = ldap_search($ds, $settings->_ldapBaseDN, "(&(".$ldapSearchAttribut.$username.")".$settings->_ldapFilter.")");
+ $search = ldap_search($ds, $settings->_ldapBaseDN, "(&(".$ldapSearchAttribut.'='.$username.")".$settings->_ldapFilter.")");
} else {
- $search = ldap_search($ds, $settings->_ldapBaseDN, $ldapSearchAttribut.$username);
+ $search = ldap_search($ds, $settings->_ldapBaseDN, $ldapSearchAttribut.'='.$username);
}
+ */
+ $search = ldap_search($ds, $settings->_ldapBaseDN, "(".$ldapsearchterm.")");
if (!is_bool($search)) {
$info = ldap_get_entries($ds, $search);
if (!is_bool($info) && $info["count"]>0) {
$dn = $info[0]['dn'];
+ /* Set username to login name in case the email was used for authentication */
+ $username = $info[0][$ldapSearchAttribut][0];
}
}
+ } elseif(!empty($settings->_enableLoginByEmail)) {
+ ldap_close($ds);
+ return null;
}
/* If the previous bind failed, try it with the users creditionals
@@ -188,8 +217,10 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication {
* If that user was filtered out, because filter was set to '(mail=*)'
* and the user doesn't have a mail address, then $dn will not be
* set and $tmpDN will be used instead, allowing a successfull bind.
+ * Also do not take the $tmpDN if login by email is allowed, because
+ * the username could be the email and that doesn't form a valid dn.
*/
- if (is_bool($dn) && empty($settings->_ldapFilter)) {
+ if (is_bool($dn) && empty($settings->_ldapFilter) && empty($settings->_enableLoginByEmail)) {
$dn = $tmpDN;
}
@@ -201,6 +232,9 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication {
/* Check if user already exists in the database. Return with an error
* only if the sql statements fails, but not if no user was found.
+ * The username may not be the one passed to this function anymore. It
+ * could have been overwritten by uid (or sAMAccountName) derived from
+ * the above ldap search.
*/
$user = $dms->getUserByLogin($username);
if($user === false) {
@@ -217,13 +251,15 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication {
// Successfully authenticated. Now check to see if the user exists within
// the database. If not, add them in if _restricted is not set,
- // but do not add their password.
+ // but do not set the password of the user.
if (!$settings->_restricted) {
- // Retrieve the user's LDAP information.
+ /* Retrieve the user's LDAP information. At this time the username is
+ * the uid or sAMAccountName, even if the email was used for login.
+ */
if (isset($settings->_ldapFilter) && strlen($settings->_ldapFilter) > 0) {
- $search = ldap_search($ds, $settings->_ldapBaseDN, "(&(".$ldapSearchAttribut.$username.")".$settings->_ldapFilter.")");
+ $search = ldap_search($ds, $settings->_ldapBaseDN, "(&(".$ldapSearchAttribut.'='.$username.")".$settings->_ldapFilter.")");
} else {
- $search = ldap_search($ds, $settings->_ldapBaseDN, $ldapSearchAttribut.$username);
+ $search = ldap_search($ds, $settings->_ldapBaseDN, $ldapSearchAttribut.'='.$username);
}
if (!is_bool($search)) {
diff --git a/inc/inc.ClassNotificationService.php b/inc/inc.ClassNotificationService.php
index a02946950..d6050a9a7 100644
--- a/inc/inc.ClassNotificationService.php
+++ b/inc/inc.ClassNotificationService.php
@@ -439,7 +439,7 @@ class SeedDMS_NotificationService {
* the currently logged in user is not the
* owner and the owner is not already in the list of notifiers.
*/
- if($user->getID() != $version->getUser()->getID() && $version->getUser()->getID() != $document->getOwner() && false === SeedDMS_Core_DMS::inList($version->getUser(), $nl['users']))
+ if($user->getID() != $version->getUser()->getID() && $version->getUser()->getID() != $document->getOwner()->getID() && false === SeedDMS_Core_DMS::inList($version->getUser(), $nl['users']))
$this->toIndividual($user, $version->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER);
} /* }}} */
@@ -573,12 +573,12 @@ class SeedDMS_NotificationService {
* the currently logged in user is not the
* owner and the owner is not already in the list of notifiers.
*/
- if($user->getID() != $content->getUser()->getID() && $content->getUser()->getID() != $document->getOwner() && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users']))
+ if($user->getID() != $content->getUser()->getID() && $content->getUser()->getID() != $document->getOwner()->getID() && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users']))
$this->toIndividual($user, $content->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER);
} /* }}} */
/**
- * This notification is sent when a new attachment is created.
+ * This notification is sent when an attachment is deleted.
*/
public function sendDeleteFileMail($file, $user) { /* {{{ */
$document = $file->getDocument();
@@ -816,10 +816,10 @@ class SeedDMS_NotificationService {
$params['sitename'] = $this->settings->_siteName;
$params['http_root'] = $this->settings->_httpRoot;
- // if user is not owner send notification to owner
- if ($user->getID() != $document->getOwner()->getID() &&
- false === SeedDMS_Core_DMS::inList($document->getOwner(), $notifyList['users'])) {
- $this->toIndividual($user, $document->getOwner(), $subject, $message, $params, SeedDMS_NotificationService::RECV_OWNER);
+ // if user is not uploader of the version send notification to uploader
+ if ($user->getID() != $content->getUser()->getID() &&
+ false === SeedDMS_Core_DMS::inList($content->getUser(), $notifyList['users'])) {
+ $this->toIndividual($user, $content->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER);
}
$this->toList($user, $notifyList["users"], $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION);
foreach ($notifyList["groups"] as $grp) {
@@ -1013,7 +1013,7 @@ class SeedDMS_NotificationService {
* the currently logged in user is not the
* owner and the owner is not already in the list of notifiers.
*/
- if($user->getID() != $content->getUser()->getID() && $content->getUser()->getID() != $document->getOwner() && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users']))
+ if($user->getID() != $content->getUser()->getID() && $content->getUser()->getID() != $document->getOwner()->getID() && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users']))
$this->toIndividual($user, $content->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER);
} /* }}} */
@@ -1125,14 +1125,16 @@ class SeedDMS_NotificationService {
/* Send mail to owner only if the currently logged in user is not the
* owner and the owner is not already in the list of notifiers.
*/
+ /*
if($user->getID() != $document->getOwner()->getID() && false === SeedDMS_Core_DMS::inList($document->getOwner(), $nl['users']))
$this->toIndividual($user, $document->getOwner(), $subject, $message, $params, SeedDMS_NotificationService::RECV_OWNER);
+ */
/* Send mail to uploader of version only if the uploader is not the owner and
* the currently logged in user is not the
* owner and the owner is not already in the list of notifiers.
*/
- if($user->getID() != $content->getUser()->getID() && $content->getUser()->getID() != $document->getOwner() && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users']))
+ if($user->getID() != $content->getUser()->getID() /* && $content->getUser()->getID() != $document->getOwner()->getID() */ && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users']))
$this->toIndividual($user, $content->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER);
} /* }}} */
@@ -1161,14 +1163,16 @@ class SeedDMS_NotificationService {
/* Send mail to owner only if the currently logged in user is not the
* owner and the owner is not already in the list of notifiers.
*/
+ /*
if($user->getID() != $document->getOwner()->getID() && false === SeedDMS_Core_DMS::inList($document->getOwner(), $nl['users']))
$this->toIndividual($user, $document->getOwner(), $subject, $message, $params, SeedDMS_NotificationService::RECV_OWNER);
+ */
/* Send mail to uploader of version only if the uploader is not the owner and
* the currently logged in user is not the
* owner and the owner is not already in the list of notifiers.
*/
- if($user->getID() != $content->getUser()->getID() && $content->getUser()->getID() != $document->getOwner() && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users']))
+ if($user->getID() != $content->getUser()->getID() /* && $content->getUser()->getID() != $document->getOwner()->getID() */ && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users']))
$this->toIndividual($user, $content->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER);
} /* }}} */
diff --git a/inc/inc.ClassSettings.php b/inc/inc.ClassSettings.php
index 7202f8a6d..cfaca62a9 100644
--- a/inc/inc.ClassSettings.php
+++ b/inc/inc.ClassSettings.php
@@ -47,6 +47,8 @@ class Settings { /* {{{ */
var $_enableGuestAutoLogin = false;
// Set to true for 2-factor Authentication
var $_enable2FactorAuthentication = false;
+ // If you want to allow login by email, set the following to true
+ var $_enableLoginByEmail = false;
// Allow users to reset their password
var $_enablePasswordForgotten = false;
// Do not allow users to change password
@@ -680,6 +682,7 @@ class Settings { /* {{{ */
$this->_enableGuestLogin = Settings::boolVal($tab["enableGuestLogin"]);
$this->_enableGuestAutoLogin = Settings::boolVal($tab["enableGuestAutoLogin"]);
$this->_enable2FactorAuthentication = Settings::boolVal($tab["enable2FactorAuthentication"]);
+ $this->_enableLoginByEmail = Settings::boolVal($tab["enableLoginByEmail"]);
$this->_enablePasswordForgotten = Settings::boolVal($tab["enablePasswordForgotten"]);
$this->_passwordStrength = intval($tab["passwordStrength"]);
$this->_passwordStrengthAlgorithm = strval($tab["passwordStrengthAlgorithm"]);
@@ -1084,6 +1087,7 @@ class Settings { /* {{{ */
$this->setXMLAttributValue($node, "enableGuestLogin", $this->_enableGuestLogin);
$this->setXMLAttributValue($node, "enableGuestAutoLogin", $this->_enableGuestAutoLogin);
$this->setXMLAttributValue($node, "enable2FactorAuthentication", $this->_enable2FactorAuthentication);
+ $this->setXMLAttributValue($node, "enableLoginByEmail", $this->_enableLoginByEmail);
$this->setXMLAttributValue($node, "enablePasswordForgotten", $this->_enablePasswordForgotten);
$this->setXMLAttributValue($node, "passwordStrength", $this->_passwordStrength);
$this->setXMLAttributValue($node, "passwordStrengthAlgorithm", $this->_passwordStrengthAlgorithm);
diff --git a/inc/inc.Language.php b/inc/inc.Language.php
index 8a31c22c1..3cbdf965f 100644
--- a/inc/inc.Language.php
+++ b/inc/inc.Language.php
@@ -404,10 +404,24 @@ function getAttributeValidationText($error, $attrname='', $attrvalue='', $regex=
} /* }}} */
function getAttributeValidationError($error, $attrname='', $attrvalue='', $regex='') { /* {{{ */
+ if(is_object($attrvalue))
+ $attrvalue = $attrvalue->getId();
switch($error) {
- case 10:
+ case 14:
return array("attr_not_in_valueset", array('attrname'=>$attrname, 'value'=>$attrvalue));
break;
+ case 13:
+ return array("attr_not_a_group", array('attrname'=>$attrname, 'value'=>$attrvalue));
+ break;
+ case 12:
+ return array("attr_not_a_user", array('attrname'=>$attrname, 'value'=>$attrvalue));
+ break;
+ case 11:
+ return array("attr_not_a_folder", array('attrname'=>$attrname, 'value'=>$attrvalue));
+ break;
+ case 10:
+ return array("attr_not_a_document", array('attrname'=>$attrname, 'value'=>$attrvalue));
+ break;
case 9:
return array("attr_malformed_date", array('attrname'=>$attrname, 'value'=>$attrvalue));
break;
diff --git a/op/op.Ajax.php b/op/op.Ajax.php
index 14dd3b617..3e66aba9e 100644
--- a/op/op.Ajax.php
+++ b/op/op.Ajax.php
@@ -122,7 +122,8 @@ switch($command) {
foreach($hits['docs'] as $hit) {
if($hit->getAccessMode($user, 'search') >= M_READ) {
if($hit->getLatestContent()) {
- $result[] = $hit->getID().'#'.$hit->getName();
+ //$result[] = $hit->getID().'#'.$hit->getName();
+ $result[] = array('type'=>'D', 'id'=>$hit->getId(), 'name'=>htmlspecialchars($hit->getName()), 'path'=>htmlspecialchars($hit->getParent()->getFolderPathPlain(true, '/')));
}
}
}
diff --git a/op/op.AttributeMgr.php b/op/op.AttributeMgr.php
index 24b94a0eb..8eccffc1d 100644
--- a/op/op.AttributeMgr.php
+++ b/op/op.AttributeMgr.php
@@ -73,8 +73,13 @@ if ($action == "addattrdef") {
if($minvalues > $maxvalues) {
UI::exitError(getMLText("admin_tools"),getMLText("attrdef_min_greater_max"));
}
- if($multiple && $valueset == '' && !in_array($type, array(SeedDMS_Core_AttributeDefinition::type_user, SeedDMS_Core_AttributeDefinition::type_group))) {
- UI::exitError(getMLText("admin_tools"),getMLText("attrdef_multiple_needs_valueset"));
+ if($multiple) {
+ if(in_array($type, array(SeedDMS_Core_AttributeDefinition::type_document, SeedDMS_Core_AttributeDefinition::type_folder))) {
+ UI::exitError(getMLText("admin_tools"),getMLText("attrdef_multiple_but_doc_or_folder"));
+ }
+ if($valueset == '' && !in_array($type, array(SeedDMS_Core_AttributeDefinition::type_user, SeedDMS_Core_AttributeDefinition::type_group))) {
+ UI::exitError(getMLText("admin_tools"),getMLText("attrdef_multiple_needs_valueset"));
+ }
}
$controller->setParam('name', $name);
@@ -150,8 +155,13 @@ else if ($action == "editattrdef") {
if($minvalues > $maxvalues) {
UI::exitError(getMLText("admin_tools"),getMLText("attrdef_min_greater_max"));
}
- if($multiple && $valueset == '' && !in_array($type, array(SeedDMS_Core_AttributeDefinition::type_user, SeedDMS_Core_AttributeDefinition::type_group))) {
- UI::exitError(getMLText("admin_tools"),getMLText("attrdef_multiple_needs_valueset"));
+ if($multiple) {
+ if(in_array($type, array(SeedDMS_Core_AttributeDefinition::type_document, SeedDMS_Core_AttributeDefinition::type_folder))) {
+ UI::exitError(getMLText("admin_tools"),getMLText("attrdef_multiple_but_doc_or_folder"));
+ }
+ if($valueset == '' && !in_array($type, array(SeedDMS_Core_AttributeDefinition::type_user, SeedDMS_Core_AttributeDefinition::type_group))) {
+ UI::exitError(getMLText("admin_tools"),getMLText("attrdef_multiple_needs_valueset"));
+ }
}
$controller->setParam('name', $name);
diff --git a/op/op.DocumentNotify.php b/op/op.DocumentNotify.php
index e0ba58116..2ba2a5d64 100644
--- a/op/op.DocumentNotify.php
+++ b/op/op.DocumentNotify.php
@@ -52,37 +52,39 @@ $action = $_POST["action"];
if (isset($_POST["userid"]) && (!is_numeric($_POST["userid"]) || $_POST["userid"]<-1)) {
UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("unknown_user"));
}
+$userid = isset($_POST["userid"]) ? $_POST["userid"] : -1;
-$userid = 0;
-if(isset($_POST["userid"]))
- $userid = $_POST["userid"];
+if ($userid > 0){
+ $u=$dms->getUser($userid);
+ if (($u->getId() != $user->getId()) && !$user->isAdmin())
+ UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("access_denied"));
+}
if (isset($_POST["groupid"]) && (!is_numeric($_POST["groupid"]) || $_POST["groupid"]<-1)) {
UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("unknown_group"));
}
-if(isset($_POST["groupid"]))
- $groupid = $_POST["groupid"];
+$groupid = isset($_POST["groupid"]) ? $_POST["groupid"] : -1;
-if (isset($_POST["groupid"])&&$_POST["groupid"]!=-1){
+if ($groupid > 0){
$group=$dms->getGroup($groupid);
if (!$group->isMember($user,true) && !$user->isAdmin())
UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("access_denied"));
}
$folder = $document->getFolder();
-$docPathHTML = getFolderPathHTML($folder, true). " / ".$document->getName()."";
if ($document->getAccessMode($user) < M_READ) {
UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("access_denied"));
}
// delete notification
-if ($action == "delnotify"){
- if ($userid) {
+if ($action == "delnotify") {
+
+ if ($userid > 0) {
$obj = $dms->getUser($userid);
$res = $document->removeNotify($userid, true);
- } elseif (isset($groupid)) {
+ } elseif ($groupid > 0) {
$obj = $dms->getGroup($groupid);
$res = $document->removeNotify($groupid, false);
}
@@ -137,7 +139,7 @@ else if ($action == "addnotify") {
break;
}
}
- if ($groupid != -1) {
+ if ($groupid > 0) {
$res = $document->addNotify($groupid, false);
switch ($res) {
case -1:
diff --git a/op/op.FolderNotify.php b/op/op.FolderNotify.php
index 903b9dc03..4156e00f1 100644
--- a/op/op.FolderNotify.php
+++ b/op/op.FolderNotify.php
@@ -53,19 +53,24 @@ if (isset($_POST["userid"]) && (!is_numeric($_POST["userid"]) || $_POST["userid"
}
$userid = isset($_POST["userid"]) ? $_POST["userid"] : -1;
+if ($userid > 0){
+ $u=$dms->getUser($userid);
+ if (($u->getId() != $user->getId()) && !$user->isAdmin())
+ UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("access_denied"));
+}
+
if (isset($_POST["groupid"]) && (!is_numeric($_POST["groupid"]) || $_POST["groupid"]<-1)) {
UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("unknown_group"));
}
+
$groupid = isset($_POST["groupid"]) ? $_POST["groupid"] : -1;
-if (isset($_POST["groupid"])&&$_POST["groupid"]!=-1){
+if ($groupid > 0){
$group=$dms->getGroup($groupid);
if (!$group->isMember($user,true) && !$user->isAdmin())
UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("access_denied"));
}
-$folderPathHTML = getFolderPathHTML($folder, true);
-
if ($folder->getAccessMode($user) < M_READ) {
UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("access_denied"));
}
@@ -74,12 +79,11 @@ if ($folder->getAccessMode($user) < M_READ) {
if ($action == "delnotify") {
if ($userid > 0) {
- $res = $folder->removeNotify($userid, true);
$obj = $dms->getUser($userid);
- }
- elseif ($groupid > 0) {
- $res = $folder->removeNotify($groupid, false);
+ $res = $folder->removeNotify($userid, true);
+ } elseif ($groupid > 0) {
$obj = $dms->getGroup($groupid);
+ $res = $folder->removeNotify($groupid, false);
}
switch ($res) {
case -1:
@@ -106,7 +110,7 @@ if ($action == "delnotify") {
// Add notification ----------------------------------------------------------
else if ($action == "addnotify") {
- if ($userid != -1) {
+ if ($userid > 0) {
$res = $folder->addNotify($userid, true);
switch ($res) {
case -1:
@@ -132,7 +136,7 @@ else if ($action == "addnotify") {
break;
}
}
- if ($groupid != -1) {
+ if ($groupid > 0) {
$res = $folder->addNotify($groupid, false);
switch ($res) {
case -1:
diff --git a/op/op.Settings.php b/op/op.Settings.php
index 6ab984b32..8e9b46bf2 100644
--- a/op/op.Settings.php
+++ b/op/op.Settings.php
@@ -198,6 +198,7 @@ if ($action == "saveSettings")
setBoolValue("enableGuestLogin");
setBoolValue("enableGuestAutoLogin");
setBoolValue("enable2FactorAuthentication");
+ setBoolValue("enableLoginByEmail");
setBoolValue("restricted");
setBoolValue("enableUserImage");
setBoolValue("disableSelfEdit");
diff --git a/out/out.DocumentNotify.php b/out/out.DocumentNotify.php
index 0dbf70976..d40d97c18 100644
--- a/out/out.DocumentNotify.php
+++ b/out/out.DocumentNotify.php
@@ -55,6 +55,7 @@ if($view) {
$view->setParam('folder', $folder);
$view->setParam('document', $document);
$view->setParam('sortusersinlist', $settings->_sortUsersInList);
+ $view->setParam('enableusersview', $settings->_enableUsersView);
$view->setParam('accessobject', $accessop);
$view($_GET);
exit;
diff --git a/out/out.FolderNotify.php b/out/out.FolderNotify.php
index 7117d6fc4..03c472df2 100644
--- a/out/out.FolderNotify.php
+++ b/out/out.FolderNotify.php
@@ -27,6 +27,7 @@ require_once("inc/inc.Init.php");
require_once("inc/inc.Extension.php");
require_once("inc/inc.DBInit.php");
require_once("inc/inc.ClassUI.php");
+require_once("inc/inc.ClassAccessOperation.php");
require_once("inc/inc.Authentication.php");
$tmp = explode('.', basename($_SERVER['SCRIPT_FILENAME']));
@@ -36,6 +37,7 @@ $accessop = new SeedDMS_AccessOperation($dms, $user, $settings);
if (!isset($_GET["folderid"]) || !is_numeric($_GET["folderid"]) || intval($_GET["folderid"])<1) {
UI::exitError(getMLText("folder_title", array("foldername" => getMLText("invalid_folder_id"))),getMLText("invalid_folder_id"));
}
+
$folder = $dms->getFolder($_GET["folderid"]);
if (!is_object($folder)) {
@@ -46,16 +48,15 @@ if ($folder->getAccessMode($user) < M_READ) {
UI::exitError(getMLText("folder_title", array("foldername" => htmlspecialchars($folder->getName()))),getMLText("access_denied"));
}
-$allUsers = $dms->getAllUsers($settings->_sortUsersInList);
-$allGroups = $dms->getAllGroups();
+/* Create object for checking access to certain operations */
+$accessop = new SeedDMS_AccessOperation($dms, null, $user, $settings);
if($view) {
$view->setParam('showtree', showtree());
$view->setParam('folder', $folder);
- $view->setParam('allusers', $allUsers);
- $view->setParam('allgroups', $allGroups);
- $view->setParam('accessobject', $accessop);
+ $view->setParam('enableusersview', $settings->_enableUsersView);
$view->setParam('sortusersinlist', $settings->_sortUsersInList);
+ $view->setParam('accessobject', $accessop);
$view($_GET);
exit;
}
diff --git a/out/out.Login.php b/out/out.Login.php
index d929c81b7..ce2f4c281 100644
--- a/out/out.Login.php
+++ b/out/out.Login.php
@@ -60,6 +60,7 @@ if($view) {
$view->setParam('enablelanguageselector', $settings->_enableLanguageSelector);
$view->setParam('enablethemeselector', $settings->_enableThemeSelector);
$view->setParam('enable2factauth', $settings->_enable2FactorAuthentication);
+ $view->setParam('defaultlanguage', $settings->_language);
$view($_GET);
exit;
}
diff --git a/restapi/index.php b/restapi/index.php
index d99ce0f1e..f9971ad41 100644
--- a/restapi/index.php
+++ b/restapi/index.php
@@ -728,13 +728,13 @@ class RestapiController { /* {{{ */
if($settings->_workflowMode == 'traditional' || $settings->_workflowMode == 'traditional_only_approval') {
// add mandatory reviewers/approvers
if($settings->_workflowMode == 'traditional') {
- $mreviewers = getMandatoryReviewers($mfolder, $userobj);
+ $mreviewers = getMandatoryReviewers($mfolder, null, $userobj);
if($mreviewers['i'])
$reviewers['i'] = array_merge($reviewers['i'], $mreviewers['i']);
if($mreviewers['g'])
$reviewers['g'] = array_merge($reviewers['g'], $mreviewers['g']);
}
- $mapprovers = getMandatoryApprovers($mfolder, $userobj);
+ $mapprovers = getMandatoryApprovers($mfolder, null, $userobj);
if($mapprovers['i'])
$approvers['i'] = array_merge($approvers['i'], $mapprovers['i']);
if($mapprovers['g'])
diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php
index 0a9455911..9e9b78582 100644
--- a/views/bootstrap/class.AttributeMgr.php
+++ b/views/bootstrap/class.AttributeMgr.php
@@ -142,10 +142,14 @@ $(document).ready( function() {
print $this->folderListHeader();
print "
";
- if ($user->isAdmin() || $groupNotify->isMember($user,true)) {
+ /* admins and members of a group may see exiting notifications */
+ if ($user->isAdmin() || /*$enableusersview || */$groupNotify->isMember($user,false)) {
+ print "
";
- if ($user->isAdmin() || $groupNotify->isMember($user,true)) {
+ /* admins and members of a group may see exiting notifications */
+ if ($user->isAdmin() || /*$enableusersview || */$groupNotify->isMember($user,false)) {
+ print "
errorMsg(getMLText('access_denied'));
+ //$this->errorMsg(getMLText('access_denied'));
}
} /* }}} */
diff --git a/views/bootstrap/styles/application.js b/views/bootstrap/styles/application.js
index c03ec5225..a5d2133f1 100644
--- a/views/bootstrap/styles/application.js
+++ b/views/bootstrap/styles/application.js
@@ -186,21 +186,42 @@ function initMost() {
});
},
/* updater is called when the item in the list is clicked. It is
- * actually provided to update the input field where you type, but here
- * we use it to update a second input field with the doc id. */
+ * provided to update the input field where you type. */
updater: function (item) {
- strarr = item.value.split("#");
target = this.$element.data('target');
- $('#'+target).attr('value', strarr[0]);
- return strarr[1];
+ $('#'+target).attr('value', item.id);
+ return item.value;
+ },
+ sorter: function(items) {
+ return items;
},
/* Set a matcher that allows any returned value */
matcher : function (item) {
return true;
},
highlighter : function (item) {
- strarr = item.split("#");
- return ' ' + strarr[1].replace(/ ' + item.name.replace(/' + item.path + '' : '');
+ },
+ /* This only works with a modified version of bootstrap typeahead located
+ * in boostrap-typeahead.js Search for 'render'
+ * The line
+ * this.render = this.options.render || this.render
+ * was added to bootstrap-typeahead.js
+ * The following function is a copy of the original render function but
+ * access item.name instead of item
+ */
+ render : function (items) {
+ var that = this
+
+ items = $(items).map(function (i, item) {
+ i = $(that.options.item).attr('data-value', item.name).attr('data-id', item.id).attr('data-type', item.type);
+ i.find('a').html(that.highlighter(item))
+ return i[0]
+ })
+
+ items.first().addClass('active')
+ this.$menu.html(items)
+ return this
}
}); /* }}} */
diff --git a/views/bootstrap4/class.Bootstrap4.php b/views/bootstrap4/class.Bootstrap4.php
index 8003e2adc..7a2fe40b1 100644
--- a/views/bootstrap4/class.Bootstrap4.php
+++ b/views/bootstrap4/class.Bootstrap4.php
@@ -727,8 +727,8 @@ background-image: linear-gradient(to bottom, #882222, #111111);;
if ($accessobject->check_view_access('FolderAccess'))
$menuitems['edit_folder_access'] = array('link'=>$this->params['settings']->_httpRoot."out/out.FolderAccess.php?folderid=".$folderID."&showtree=".showtree(), 'label'=>getMLText('edit_folder_access'));
}
- if ($accessobject->check_controller_access('FolderNotify'))
- $menuitems['edit_existing_notify'] = array('link'=>$this->params['settings']->_httpRoot."out/out.FolderNotify.php?folderid=". $folderID ."&showtree=". showtree(), 'label'=>getMLText('edit_existing_notify'));
+ if ($accessobject->check_view_access('FolderNotify'))
+ $menuitems['edit_folder_notify'] = array('link'=>$this->params['settings']->_httpRoot."out/out.FolderNotify.php?folderid=". $folderID ."&showtree=". showtree(), 'label'=>getMLText('edit_folder_notify'));
}
if($enableClipboard) {
$menuitems['add_to_clipboard'] = array('class'=>'addtoclipboard', 'attributes'=>array(['rel', 'F'.$folder->getId()], ['msg', getMLText('splash_added_to_clipboard')], ['title', getMLText("add_to_clipboard")]), 'label'=>getMLText("add_to_clipboard"));
@@ -804,7 +804,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);;
}
if ($accessMode >= M_READ && !$this->params['user']->isGuest()) {
if ($accessobject->check_view_access('DocumentNotify'))
- $menuitems['edit_existing_notify'] = array('link'=>$this->params['settings']->_httpRoot."out/out.DocumentNotify". $docid, 'label'=>getMLText('edit_existing_notify'));
+ $menuitems['edit_document_notify'] = array('link'=>$this->params['settings']->_httpRoot."out/out.DocumentNotify". $docid, 'label'=>getMLText('edit_document_notify'));
}
if($enableClipboard) {
$menuitems['add_to_clipboard'] = array('class'=>'addtoclipboard', 'attributes'=>array(['rel', 'D'.$document->getId()], ['msg', getMLText('splash_added_to_clipboard')], ['title', getMLText("add_to_clipboard")]), 'label'=>getMLText("add_to_clipboard"));
diff --git a/views/bootstrap4/styles/application.js b/views/bootstrap4/styles/application.js
index ae87f474a..d2375d10a 100644
--- a/views/bootstrap4/styles/application.js
+++ b/views/bootstrap4/styles/application.js
@@ -193,21 +193,42 @@ function initMost() {
});
},
/* updater is called when the item in the list is clicked. It is
- * actually provided to update the input field where you type, but here
- * we use it to update a second input field with the doc id. */
+ * provided to update the input field where you type. */
updater: function (item) {
- strarr = item.value.split("#");
target = this.$element.data('target');
- $('#'+target).attr('value', strarr[0]);
- return strarr[1];
+ $('#'+target).attr('value', item.id);
+ return item.value;
+ },
+ sorter: function(items) {
+ return items;
},
/* Set a matcher that allows any returned value */
matcher : function (item) {
return true;
},
highlighter : function (item) {
- strarr = item.split("#");
- return ' ' + strarr[1].replace(/ ' + item.name.replace(/' + item.path + '' : '');
+ },
+ /* This only works with a modified version of bootstrap typeahead located
+ * in boostrap-typeahead.js Search for 'render'
+ * The line
+ * this.render = this.options.render || this.render
+ * was added to bootstrap-typeahead.js
+ * The following function is a copy of the original render function but
+ * access item.name instead of item
+ */
+ render : function (items) {
+ var that = this
+
+ items = $(items).map(function (i, item) {
+ i = $(that.options.item).attr('data-value', item.name).attr('data-id', item.id).attr('data-type', item.type);
+ i.find('a').html(that.highlighter(item))
+ return i[0]
+ })
+
+ items.first().addClass('active')
+ this.$menu.html(items)
+ return this
}
}); /* }}} */