Bugfixes, Postgres improved support
This commit is contained in:
		
							parent
							
								
									2bbc895496
								
							
						
					
					
						commit
						a0b935c082
					
				| @ -62,7 +62,7 @@ namespace Api\Routes { | ||||
|           "action"  => $row["action"], | ||||
|           "target"  => $row["target"], | ||||
|           "extra"   => $row["extra"] ?? "", | ||||
|           "active"  => intval($row["active"]), | ||||
|           "active"  => intval($sql->parseBool($row["active"])), | ||||
|         ); | ||||
|       } | ||||
| 
 | ||||
| @ -147,7 +147,6 @@ namespace Api\Routes { | ||||
|         return false; | ||||
|       } | ||||
| 
 | ||||
| 
 | ||||
|       $sql = $this->user->getSQL(); | ||||
| 
 | ||||
|       // DELETE old rules
 | ||||
| @ -190,7 +189,7 @@ namespace Api\Routes { | ||||
| 
 | ||||
|           $value = $route[$key]; | ||||
|           $type = Parameter::parseType($value); | ||||
|           if ($type !== $expectedType && ($key !== "active" || !is_null($value))) { | ||||
|           if ($type !== $expectedType) { | ||||
|             $expectedTypeName = Parameter::names[$expectedType]; | ||||
|             $gotTypeName = Parameter::names[$type]; | ||||
|             return $this->createError("Route $index has invalid value for key: $key, expected: $expectedTypeName, got: $gotTypeName"); | ||||
| @ -218,6 +217,5 @@ namespace Api\Routes { | ||||
|       return true; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -5,6 +5,7 @@ use Api\Parameter\Parameter; | ||||
| use Api\Parameter\StringType; | ||||
| use External\PHPMailer\Exception; | ||||
| use External\PHPMailer\PHPMailer; | ||||
| use Objects\ConnectionData; | ||||
| 
 | ||||
| class SendMail extends Request { | ||||
| 
 | ||||
| @ -20,17 +21,39 @@ class SendMail extends Request { | ||||
|     $this->isPublic = false; | ||||
|   } | ||||
| 
 | ||||
|   private function getMailConfig() : ?ConnectionData { | ||||
|     $req = new \Api\Settings\Get($this->user); | ||||
|     $this->success = $req->execute(array("key" => "^mail_")); | ||||
|     $this->lastError = $req->getLastError(); | ||||
| 
 | ||||
|     if ($this->success) { | ||||
|       $settings = $req->getResult()["settings"]; | ||||
|       if (!isset($settings["mail_enabled"]) || $settings["mail_enabled"] !== "1") { | ||||
|         $this->createError("Mail is not configured yet."); | ||||
|         return null; | ||||
|       } | ||||
| 
 | ||||
|       $host = $settings["mail_host"] ?? "localhost"; | ||||
|       $port = intval($settings["mail_port"] ?? "25"); | ||||
|       $login = $settings["mail_username"] ?? ""; | ||||
|       $password = $settings["mail_password"] ?? ""; | ||||
|       return new ConnectionData($host, $port, $login, $password); | ||||
|     } | ||||
| 
 | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   public function execute($values = array()) { | ||||
|     if(!parent::execute($values)) { | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|     try { | ||||
|       $mailConfig = $this->user->getConfiguration()->getMail(); | ||||
|       if (!$mailConfig) { | ||||
|         return $this->createError("Mail is not configured yet."); | ||||
|       } | ||||
|     $mailConfig = $this->getMailConfig(); | ||||
|     if (!$this->success) { | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|     try { | ||||
|       $mail = new PHPMailer; | ||||
|       $mail->IsSMTP(); | ||||
|       $mail->setFrom($this->getParam('from'), $this->getParam('fromName')); | ||||
|  | ||||
							
								
								
									
										112
									
								
								core/Api/SettingsAPI.class.php
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										112
									
								
								core/Api/SettingsAPI.class.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,112 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Api { | ||||
| 
 | ||||
|   class SettingsAPI extends Request { | ||||
| 
 | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| namespace Api\Settings { | ||||
| 
 | ||||
|   use Api\Parameter\Parameter; | ||||
|   use Api\Parameter\StringType; | ||||
|   use Api\SettingsAPI; | ||||
|   use Driver\SQL\Column\Column; | ||||
|   use Driver\SQL\Condition\CondLike; | ||||
|   use Driver\SQL\Condition\CondRegex; | ||||
|   use Driver\SQL\Strategy\UpdateStrategy; | ||||
|   use Objects\User; | ||||
| 
 | ||||
|   class Get extends SettingsAPI { | ||||
| 
 | ||||
|     public function __construct(User $user, bool $externalCall = false) { | ||||
|       parent::__construct($user, $externalCall, array( | ||||
|         'key' => new StringType('key', 32, true, NULL) | ||||
|       )); | ||||
| 
 | ||||
|       $this->requiredGroup = array(USER_GROUP_ADMIN); | ||||
|       $this->loginRequired = true; | ||||
|     } | ||||
| 
 | ||||
|     public function execute($values = array()) { | ||||
|        if(!parent::execute($values)) { | ||||
|          return false; | ||||
|        } | ||||
| 
 | ||||
|        $key = $this->getParam("key"); | ||||
|        $sql = $this->user->getSQL(); | ||||
| 
 | ||||
|        $query = $sql->select("name", "value") ->from("Settings"); | ||||
| 
 | ||||
|        if (!is_null($key) && !empty($key)) { | ||||
|          $query->where(new CondRegex($key, new Column("name"))); | ||||
|        } | ||||
| 
 | ||||
|        $res = $query->execute(); | ||||
| 
 | ||||
|        $this->success = ($res !== FALSE); | ||||
|        $this->lastError = $sql->getLastError(); | ||||
| 
 | ||||
|        if ($this->success) { | ||||
|          $settings = array(); | ||||
|          foreach($res as $row) { | ||||
|            $settings[$row["name"]] = $row["value"]; | ||||
|          } | ||||
|          $this->result["settings"] = $settings; | ||||
|        } | ||||
| 
 | ||||
|        return $this->success; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   class Set extends SettingsAPI { | ||||
|     public function __construct(User $user, bool $externalCall = false) { | ||||
|       parent::__construct($user, $externalCall, array( | ||||
|         'settings' => new Parameter('settings', Parameter::TYPE_ARRAY) | ||||
|       )); | ||||
| 
 | ||||
|       $this->requiredGroup = array(USER_GROUP_ADMIN); | ||||
|       $this->loginRequired = true; | ||||
|     } | ||||
| 
 | ||||
|     public function execute($values = array()) { | ||||
|       if (!parent::execute($values)) { | ||||
|         return false; | ||||
|       } | ||||
| 
 | ||||
|       $values = $this->getParam("settings"); | ||||
|       if (empty($values)) { | ||||
|         return $this->createError("No values given."); | ||||
|       } | ||||
| 
 | ||||
|       $paramKey = new StringType('key', 32); | ||||
|       $paramValue = new StringType('value', 1024); | ||||
| 
 | ||||
|       $sql = $this->user->getSQL(); | ||||
|       $query = $sql->insert("Settings", array("name", "value")); | ||||
| 
 | ||||
|       foreach($values as $key => $value) { | ||||
|         if (!$paramKey->parseParam($key)) { | ||||
|           $key = print_r($key, true); | ||||
|           return $this->createError("Invalid Type for key in parameter settings: '$key' (Required: " . $paramKey->getTypeName() . ")"); | ||||
|         } else if(!$paramValue->parseParam($value)) { | ||||
|           $value = print_r($value, true); | ||||
|           return $this->createError("Invalid Type for value in parameter settings: '$value' (Required: " . $paramValue->getTypeName() . ")"); | ||||
|         } else { | ||||
|           $query->addRow($paramKey->value, $paramValue->value); | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       $query->onDuplicateKeyStrategy(new UpdateStrategy( | ||||
|         array("name"), | ||||
|         array("value" => new Column("value"))) | ||||
|       ); | ||||
| 
 | ||||
|       $this->success = ($query->execute() !== FALSE); | ||||
|       $this->lastError = $sql->getLastError(); | ||||
|       return $this->success; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -67,6 +67,17 @@ class Stats extends Request { | ||||
|     return $visitors; | ||||
|   } | ||||
| 
 | ||||
|   private function isMailConfigured() { | ||||
|     $req = new \Api\Settings\Get($this->user); | ||||
|     $this->success = $req->execute(array("key" => "^mail_enabled$")); | ||||
| 
 | ||||
|     if ($this->success) { | ||||
|       return ($req->getResult()["mail_enabled"] ?? "0") === "1"; | ||||
|     } | ||||
| 
 | ||||
|     return $this->success; | ||||
|   } | ||||
| 
 | ||||
|   public function execute($values = array()) { | ||||
|     if(!parent::execute($values)) { | ||||
|       return false; | ||||
| @ -75,26 +86,32 @@ class Stats extends Request { | ||||
|     $userCount = $this->getUserCount(); | ||||
|     $pageCount = $this->getPageCount(); | ||||
|     $visitorStatistics = $this->getVisitorStatistics(); | ||||
|     if (!$this->success) { | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|     $loadAvg = "Unknown"; | ||||
|     if (function_exists("sys_getloadavg")) { | ||||
|       $loadAvg = sys_getloadavg(); | ||||
|     } | ||||
| 
 | ||||
|     if ($this->success) { | ||||
|       $this->result["userCount"] = $userCount; | ||||
|       $this->result["pageCount"] = $pageCount; | ||||
|       $this->result["visitors"] = $visitorStatistics; | ||||
|       $this->result["server"] = array( | ||||
|         "version" => WEBBASE_VERSION, | ||||
|         "server" => $_SERVER["SERVER_SOFTWARE"] ?? "Unknown", | ||||
|         "memory_usage" => memory_get_usage(), | ||||
|         "load_avg" => $loadAvg, | ||||
|         "database" => $this->user->getSQL()->getStatus(), | ||||
|         "mail" => $this->user->getConfiguration()->getMail() !== NULL | ||||
|       ); | ||||
|     $mailConfigured = $this->isMailConfigured(); | ||||
|     if (!$this->success) { | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|     $this->result["userCount"] = $userCount; | ||||
|     $this->result["pageCount"] = $pageCount; | ||||
|     $this->result["visitors"] = $visitorStatistics; | ||||
|     $this->result["server"] = array( | ||||
|       "version" => WEBBASE_VERSION, | ||||
|       "server" => $_SERVER["SERVER_SOFTWARE"] ?? "Unknown", | ||||
|       "memory_usage" => memory_get_usage(), | ||||
|       "load_avg" => $loadAvg, | ||||
|       "database" => $this->user->getSQL()->getStatus(), | ||||
|       "mail" => $mailConfigured | ||||
|     ); | ||||
| 
 | ||||
|     return $this->success; | ||||
|   } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										2
									
								
								core/Configuration/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								core/Configuration/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,3 +1 @@ | ||||
| Mail\.class\.php | ||||
| JWT\.class\.php | ||||
| Database\.class\.php | ||||
|  | ||||
| @ -2,53 +2,33 @@ | ||||
| 
 | ||||
| namespace Configuration; | ||||
| 
 | ||||
| use Error; | ||||
| use Objects\ConnectionData; | ||||
| 
 | ||||
| class Configuration { | ||||
| 
 | ||||
|   private ?ConnectionData $database; | ||||
|   private ?ConnectionData $mail; | ||||
|   private ?KeyData $jwt; | ||||
|   private Settings $settings; | ||||
| 
 | ||||
|   function __construct() { | ||||
|   } | ||||
|     $this->database = null; | ||||
|     $this->settings = Settings::loadDefaults(); | ||||
| 
 | ||||
|   public function load() { | ||||
|     try { | ||||
| 
 | ||||
|       $classes = array( | ||||
|         \Configuration\Database::class => &$this->database, | ||||
|         \Configuration\Mail::class => &$this->mail, | ||||
|         \Configuration\JWT::class => &$this->jwt | ||||
|       ); | ||||
| 
 | ||||
|       $success = true; | ||||
|       foreach($classes as $class => &$ref) { | ||||
|         $path = getClassPath($class); | ||||
|         if(!file_exists($path)) { | ||||
|           $success = false; | ||||
|         } else { | ||||
|           include_once $path; | ||||
|           if(class_exists($class)) { | ||||
|             $ref = new $class(); | ||||
|           } | ||||
|         } | ||||
|     $class = \Configuration\Database::class; | ||||
|     $path = getClassPath($class, true); | ||||
|     if(file_exists($path) && is_readable($path)) { | ||||
|       include_once $path; | ||||
|       if(class_exists($class)) { | ||||
|         $this->database = new \Configuration\Database(); | ||||
|       } | ||||
| 
 | ||||
|       return $success; | ||||
|     } catch(Error $e) { | ||||
|       die($e); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   public function getDatabase() { return $this->database; } | ||||
|   public function getJWT() { return $this->jwt; } | ||||
|   public function getMail() { return $this->mail; } | ||||
|   public function getDatabase() : ?ConnectionData { | ||||
|     return $this->database; | ||||
|   } | ||||
| 
 | ||||
|   public function isFilePresent($className) { | ||||
|     $path = getClassPath("\\Configuration\\$className"); | ||||
|     return file_exists($path); | ||||
|   public function getSettings() : Settings { | ||||
|     return $this->settings; | ||||
|   } | ||||
| 
 | ||||
|   public function create(string $className, $data) { | ||||
|  | ||||
| @ -8,6 +8,9 @@ use \Driver\SQL\Strategy\CascadeStrategy; | ||||
| 
 | ||||
| class CreateDatabase { | ||||
| 
 | ||||
|   // NOTE:
 | ||||
|   // explicit serial ids removed due to postgres' serial implementation
 | ||||
| 
 | ||||
|   public static function createQueries(SQL $sql) { | ||||
|     $queries = array(); | ||||
| 
 | ||||
| @ -21,8 +24,8 @@ class CreateDatabase { | ||||
|       ->unique("name"); | ||||
| 
 | ||||
|     $queries[] = $sql->insert("Language", array("uid", "code", "name")) | ||||
|       ->addRow(1, "en_US", 'American English') | ||||
|       ->addRow(2, "de_DE", 'Deutsch Standard'); | ||||
|       ->addRow( "en_US", 'American English') | ||||
|       ->addRow( "de_DE", 'Deutsch Standard'); | ||||
| 
 | ||||
|     $queries[] = $sql->createTable("User") | ||||
|       ->addSerial("uid") | ||||
| @ -72,9 +75,9 @@ class CreateDatabase { | ||||
|       ->unique("name"); | ||||
| 
 | ||||
|     $queries[] = $sql->insert("Group", array("uid", "name", "color")) | ||||
|       ->addRow(USER_GROUP_MODERATOR, USER_GROUP_MODERATOR_NAME, "#007bff") | ||||
|       ->addRow(USER_GROUP_SUPPORT, USER_GROUP_SUPPORT_NAME, "#28a745") | ||||
|       ->addRow(USER_GROUP_ADMIN, USER_GROUP_ADMIN_NAME, "#dc3545"); | ||||
|       ->addRow(USER_GROUP_MODERATOR_NAME, "#007bff") | ||||
|       ->addRow(USER_GROUP_SUPPORT_NAME, "#28a745") | ||||
|       ->addRow(USER_GROUP_ADMIN_NAME, "#dc3545"); | ||||
| 
 | ||||
|     $queries[] = $sql->createTable("UserGroup") | ||||
|       ->addInt("user_id") | ||||
| @ -137,6 +140,22 @@ class CreateDatabase { | ||||
|       ->addRow("^/acceptInvite(/)?$", "dynamic", "\\Documents\\Account", "\\Views\\Account\\AcceptInvite") | ||||
|       ->addRow("^/$", "static", "/static/welcome.html", NULL); | ||||
| 
 | ||||
|     $queries[] = $sql->createTable("Settings") | ||||
|       ->addString("name", 32) | ||||
|       ->addString("value", 1024, true) | ||||
|       ->primaryKey("name"); | ||||
| 
 | ||||
|     $settingsQuery = $sql->insert("Settings", array("name", "value")) | ||||
|       // ->addRow("mail_enabled", "0") # this key will be set during installation
 | ||||
|       ->addRow("mail_host", "") | ||||
|       ->addRow("mail_port", "") | ||||
|       ->addRow("mail_username", "") | ||||
|       ->addRow("mail_password", "") | ||||
|       ->addRow("mail_from", ""); | ||||
| 
 | ||||
|     (Settings::loadDefaults())->addRows($settingsQuery); | ||||
|     $queries[] = $settingsQuery; | ||||
| 
 | ||||
|     return $queries; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,17 +0,0 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Configuration; | ||||
| 
 | ||||
| class KeyData { | ||||
| 
 | ||||
|     protected string $key; | ||||
| 
 | ||||
|     public function __construct(string $key) { | ||||
|         $this->key = $key; | ||||
|     } | ||||
| 
 | ||||
|     public function getKey() { | ||||
|         return $this->key; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										71
									
								
								core/Configuration/Settings.class.php
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										71
									
								
								core/Configuration/Settings.class.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | ||||
| <?php | ||||
| 
 | ||||
| /** | ||||
|  * Do not change settings here, they are dynamically loaded from database. | ||||
|  */ | ||||
| 
 | ||||
| namespace Configuration; | ||||
| 
 | ||||
| use Driver\SQL\Query\Insert; | ||||
| use Objects\User; | ||||
| 
 | ||||
| class Settings { | ||||
| 
 | ||||
|   private string $siteName; | ||||
|   private string $baseUrl; | ||||
|   private string $jwtSecret; | ||||
|   private bool $installationComplete; | ||||
|   private bool $registrationAllowed; | ||||
| 
 | ||||
|   public function getJwtSecret(): string { | ||||
|     return $this->jwtSecret; | ||||
|   } | ||||
| 
 | ||||
|   public function isInstalled() { | ||||
|     return $this->installationComplete; | ||||
|   } | ||||
| 
 | ||||
|   public static function loadDefaults() : Settings { | ||||
|     $hostname = php_uname("n"); | ||||
|     $protocol = getProtocol(); | ||||
|     $jwt = generateRandomString(32); | ||||
| 
 | ||||
|     $settings = new Settings(); | ||||
|     $settings->siteName = "WebBase"; | ||||
|     $settings->baseUrl = "$protocol://$hostname"; | ||||
|     $settings->jwtSecret = $jwt; | ||||
|     $settings->installationComplete = false; | ||||
|     $settings->registrationAllowed = false; | ||||
|     return $settings; | ||||
|   } | ||||
| 
 | ||||
|   public function loadFromDatabase(User $user) { | ||||
|     $req = new \Api\Settings\Get($user); | ||||
|     $success = $req->execute(); | ||||
| 
 | ||||
|     if ($success) { | ||||
|       $result = $req->getResult()["settings"]; | ||||
|       $this->siteName = $result["site_name"] ?? $this->siteName; | ||||
|       $this->registrationAllowed = $result["user_registration_enabled"] ?? $this->registrationAllowed; | ||||
|       $this->installationComplete = $result["installation_completed"] ?? $this->installationComplete; | ||||
|       $this->jwtSecret = $result["jwt_secret"] ?? $this->jwtSecret; | ||||
| 
 | ||||
|       if (!isset($result["jwt_secret"])) { | ||||
|         $req = new \Api\Settings\Set($user); | ||||
|         $req->execute(array("settings" => array( | ||||
|           "jwt_secret" => $this->jwtSecret | ||||
|         ))); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   public function addRows(Insert $query) { | ||||
|     $query->addRow("site_name", $this->siteName) | ||||
|       ->addRow("base_url", $this->baseUrl) | ||||
|       ->addRow("user_registration_enabled", $this->registrationAllowed ? "1" : "0") | ||||
|       ->addRow("installation_completed", $this->installationComplete ? "1" : "0") | ||||
|       ->addRow("jwt_secret", $this->jwtSecret); | ||||
|   } | ||||
| } | ||||
| @ -16,8 +16,6 @@ namespace Documents { | ||||
| 
 | ||||
| namespace Documents\Install { | ||||
| 
 | ||||
|   use Api\Notifications\Create; | ||||
|   use Api\Parameter\Parameter; | ||||
|   use Configuration\CreateDatabase; | ||||
|   use Driver\SQL\SQL; | ||||
|   use Elements\Body; | ||||
| @ -113,6 +111,10 @@ namespace Documents\Install { | ||||
|       } | ||||
| 
 | ||||
|       $sql = $user->getSQL(); | ||||
|       if(!$sql || !$sql->isConnected()) { | ||||
|         return self::DATABASE_CONFIGURATION; | ||||
|       } | ||||
| 
 | ||||
|       $countKeyword = $sql->count(); | ||||
|       $res = $sql->select($countKeyword)->from("User")->execute(); | ||||
|       if ($res === FALSE) { | ||||
| @ -125,19 +127,28 @@ namespace Documents\Install { | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       if($step === self::ADD_MAIL_SERVICE && $config->isFilePresent("Mail")) { | ||||
|         $step = self::FINISH_INSTALLATION; | ||||
|         if(!$config->isFilePresent("JWT") && !$config->create("JWT", generateRandomString(32))) { | ||||
|           $this->errorString = "Unable to create jwt file"; | ||||
|         } else { | ||||
|           $req = new Create($user); | ||||
|           $success = $req->execute(array( | ||||
|             "title" => "Welcome", | ||||
|             "message" => "Your Web-base was successfully installed. Check out the admin dashboard. Have fun!", | ||||
|             "groupId" => USER_GROUP_ADMIN) | ||||
|           ); | ||||
|       if ($step === self::ADD_MAIL_SERVICE) { | ||||
|         $req = new \Api\Settings\Get($user); | ||||
|         $success = $req->execute(array("key" => "^mail_enabled$")); | ||||
|         if (!$success) { | ||||
|           $this->errorString = $req->getLastError(); | ||||
|           return self::DATABASE_CONFIGURATION; | ||||
|         } else if (isset($req->getResult()["settings"]["mail_enabled"])) { | ||||
|           $step = self::FINISH_INSTALLATION; | ||||
| 
 | ||||
|           $req = new \Api\Settings\Set($user); | ||||
|           $success = $req->execute(array("settings" => array("installation_completed" => "1"))); | ||||
|           if (!$success) { | ||||
|             $this->errorString = $req->getLastError(); | ||||
|           } else { | ||||
|             $req = new \Api\Notifications\Create($user); | ||||
|             $success = $req->execute(array( | ||||
|                 "title" => "Welcome", | ||||
|                 "message" => "Your Web-base was successfully installed. Check out the admin dashboard. Have fun!", | ||||
|                 "groupId" => USER_GROUP_ADMIN | ||||
|               ) | ||||
|             ); | ||||
|             $this->errorString = $req->getLastError(); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
| @ -264,7 +275,8 @@ namespace Documents\Install { | ||||
|             } | ||||
|           } | ||||
| 
 | ||||
|           if($success && !$this->getDocument()->getUser()->getConfiguration()->create("Database", $connectionData)) { | ||||
|           $config = $this->getDocument()->getUser()->getConfiguration(); | ||||
|           if(!$config->create("Database", $connectionData)) { | ||||
|             $success = false; | ||||
|             $msg = "Unable to write file"; | ||||
|           } | ||||
| @ -348,10 +360,9 @@ namespace Documents\Install { | ||||
|       $success = true; | ||||
|       $msg = $this->errorString; | ||||
|       if($this->getParameter("skip") === "true") { | ||||
|         if(!$user->getConfiguration()->create("Mail", null)) { | ||||
|           $success = false; | ||||
|           $msg = "Unable to create file"; | ||||
|         } | ||||
|         $req = new \Api\Settings\Set($user); | ||||
|         $success = $req->execute(array("settings" => array( "mail_enabled" => "0" ))); | ||||
|         $msg = $req->getLastError(); | ||||
|       } else { | ||||
| 
 | ||||
|         $address = $this->getParameter("address"); | ||||
| @ -415,11 +426,15 @@ namespace Documents\Install { | ||||
|           } | ||||
| 
 | ||||
|           if($success) { | ||||
|             $connectionData = new ConnectionData($address, $port, $username, $password); | ||||
|             if(!$user->getConfiguration()->create("Mail", $connectionData)) { | ||||
|               $success = false; | ||||
|               $msg = "Unable to create file"; | ||||
|             } | ||||
|             $req = new \Api\Settings\Set($user); | ||||
|             $success = $req->execute(array("settings" => array( | ||||
|               "mail_enabled" => "1", | ||||
|               "mail_host" => "$address", | ||||
|               "mail_port" => "$port", | ||||
|               "mail_username" => "$username", | ||||
|               "mail_password" => "$password", | ||||
|             ))); | ||||
|             $msg = $req->getLastError(); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
| @ -461,26 +476,26 @@ namespace Documents\Install { | ||||
| 
 | ||||
|         switch($status) { | ||||
|           case self::PENDING: | ||||
|             $statusIcon  = '<i class="fas fa-spin fa-spinner"></i>'; | ||||
|             $statusIcon  = $this->createIcon("spinner"); | ||||
|             $statusText  = "Loading…"; | ||||
|             $statusColor = "muted"; | ||||
|             break; | ||||
| 
 | ||||
|           case self::SUCCESSFUL: | ||||
|             $statusIcon  = '<i class="fas fa-check-circle"></i>'; | ||||
|             $statusIcon  = $this->createIcon("check-circle"); | ||||
|             $statusText  = "Successful"; | ||||
|             $statusColor = "success"; | ||||
|             break; | ||||
| 
 | ||||
|           case self::ERROR: | ||||
|             $statusIcon  = '<i class="fas fa-times-circle"></i>'; | ||||
|             $statusIcon  = $this->createIcon("times-circle"); | ||||
|             $statusText  = "Failed"; | ||||
|             $statusColor = "danger"; | ||||
|             break; | ||||
| 
 | ||||
|           case self::NOT_STARTED: | ||||
|           default: | ||||
|             $statusIcon = '<i class="far fa-circle"></i>'; | ||||
|             $statusIcon = $this->createIcon("circle", "far"); | ||||
|             $statusText = "Pending"; | ||||
|             $statusColor = "muted"; | ||||
|             break; | ||||
| @ -797,6 +812,5 @@ namespace Documents\Install { | ||||
| 
 | ||||
|       return $html; | ||||
|     } | ||||
| 
 | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -173,7 +173,7 @@ class MySQL extends SQL { | ||||
|         $leftColumn = $this->columnName($key); | ||||
|         if ($value instanceof Column) { | ||||
|           $columnName = $this->columnName($value->getName()); | ||||
|           $updateValues[] = "$leftColumn=$columnName"; | ||||
|           $updateValues[] = "$leftColumn=VALUES($columnName)"; | ||||
|         } else if($value instanceof Add) { | ||||
|           $columnName = $this->columnName($value->getColumn()); | ||||
|           $operator = $value->getOperator(); | ||||
|  | ||||
| @ -139,7 +139,7 @@ class PostgreSQL extends SQL { | ||||
|                 $leftColumn = $this->columnName($key); | ||||
|                 if ($value instanceof Column) { | ||||
|                   $columnName = $this->columnName($value->getName()); | ||||
|                   $updateValues[] = "$leftColumn=$columnName"; | ||||
|                   $updateValues[] = "$leftColumn=EXCLUDED.$columnName"; | ||||
|                 } else if ($value instanceof Add) { | ||||
|                   $columnName = $this->columnName($value->getColumn()); | ||||
|                   $operator = $value->getOperator(); | ||||
|  | ||||
| @ -215,7 +215,9 @@ abstract class SQL { | ||||
|   } | ||||
| 
 | ||||
|   public function executeTruncate(Truncate $truncate) { | ||||
|     return $this->execute("TRUNCATE " . $truncate->getTable()); | ||||
|     $query = "TRUNCATE " . $this->tableName($truncate->getTable()); | ||||
|     if ($truncate->dump) { var_dump($query); } | ||||
|     return $this->execute($query); | ||||
|   } | ||||
| 
 | ||||
|   public function executeUpdate(Update $update) { | ||||
| @ -391,4 +393,8 @@ abstract class SQL { | ||||
|   } | ||||
| 
 | ||||
|   public abstract function getStatus(); | ||||
| 
 | ||||
|   public function parseBool($val) : bool { | ||||
|     return in_array($val, array(true, 1, '1', 't', 'true', 'TRUE')); | ||||
|   } | ||||
| } | ||||
| @ -94,7 +94,7 @@ abstract class View extends StaticView { | ||||
|   protected function createIcon($icon, $type = "fas", $classes = "") { | ||||
|     $iconClass = "$type fa-$icon"; | ||||
| 
 | ||||
|     if($icon === "spinner") | ||||
|     if($icon === "spinner" || $icon === "circle-notch") | ||||
|       $iconClass .= " fa-spin"; | ||||
| 
 | ||||
|     if($classes) | ||||
|  | ||||
| @ -62,13 +62,11 @@ class Session extends ApiObject { | ||||
| 
 | ||||
|   public function sendCookie() { | ||||
|     $this->updateMetaData(); | ||||
|     $jwt = $this->user->getConfiguration()->getJwt(); | ||||
|     if($jwt) { | ||||
|       $token = array('userId' => $this->user->getId(), 'sessionId' => $this->sessionId); | ||||
|       $sessionCookie = JWT::encode($token, $jwt->getKey()); | ||||
|       $secure = strcmp(getProtocol(), "https") === 0; | ||||
|       setcookie('session', $sessionCookie, $this->getExpiresTime(), "/", "", $secure); | ||||
|     } | ||||
|     $settings = $this->user->getConfiguration()->getSettings(); | ||||
|     $token = array('userId' => $this->user->getId(), 'sessionId' => $this->sessionId); | ||||
|     $sessionCookie = JWT::encode($token, $settings->getJwtSecret()); | ||||
|     $secure = strcmp(getProtocol(), "https") === 0; | ||||
|     setcookie('session', $sessionCookie, $this->getExpiresTime(), "/", "", $secure); | ||||
|   } | ||||
| 
 | ||||
|   public function getExpiresTime() { | ||||
|  | ||||
| @ -43,6 +43,10 @@ class User extends ApiObject { | ||||
|     $databaseConf = $this->configuration->getDatabase(); | ||||
|     if($databaseConf) { | ||||
|       $this->sql = SQL::createConnection($databaseConf); | ||||
|       if ($this->sql->isConnected()) { | ||||
|         $settings = $this->configuration->getSettings(); | ||||
|         $settings->loadFromDatabase($this); | ||||
|       } | ||||
|     } else { | ||||
|       $this->sql = null; | ||||
|     } | ||||
| @ -155,7 +159,7 @@ class User extends ApiObject { | ||||
|         $this->uid = $userId; | ||||
|         $this->session = new Session($this, $sessionId, $csrfToken); | ||||
|         $this->session->setData(json_decode($row["data"] ?? '{}')); | ||||
|         $this->session->stayLoggedIn($row["stay_logged_in"]); | ||||
|         $this->session->stayLoggedIn($this->sql->parseBool(["stay_logged_in"])); | ||||
|         if($sessionUpdate) $this->session->update(); | ||||
|         $this->loggedIn = true; | ||||
| 
 | ||||
| @ -175,11 +179,11 @@ class User extends ApiObject { | ||||
|   private function parseCookies() { | ||||
|     if(isset($_COOKIE['session']) | ||||
|       && is_string($_COOKIE['session']) | ||||
|       && !empty($_COOKIE['session']) | ||||
|       && ($jwt = $this->configuration->getJWT())) { | ||||
|       && !empty($_COOKIE['session'])) { | ||||
|       try { | ||||
|         $token = $_COOKIE['session']; | ||||
|         $decoded = (array)JWT::decode($token, $jwt->getKey()); | ||||
|         $settings = $this->configuration->getSettings(); | ||||
|         $decoded = (array)JWT::decode($token, $settings->getJwtSecret()); | ||||
|         if(!is_null($decoded)) { | ||||
|           $userId = (isset($decoded['userId']) ? $decoded['userId'] : NULL); | ||||
|           $sessionId = (isset($decoded['sessionId']) ? $decoded['sessionId'] : NULL); | ||||
|  | ||||
| @ -25,8 +25,10 @@ spl_autoload_register(function($class) { | ||||
| }); | ||||
| 
 | ||||
| $config = new Configuration(); | ||||
| $installation = (!$config->load()); | ||||
| $user   = new Objects\User($config); | ||||
| $sql    = $user->getSQL(); | ||||
| $settings = $config->getSettings(); | ||||
| $installation = !$sql || ($sql->isConnected() && !$settings->isInstalled()); | ||||
| 
 | ||||
| if(isset($_GET["api"]) && is_string($_GET["api"])) { | ||||
|   header("Content-Type: application/json"); | ||||
|  | ||||
							
								
								
									
										2
									
								
								js/admin.min.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								js/admin.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -126,7 +126,7 @@ export default class CreateGroup extends React.Component { | ||||
|                 this.setState({...this.state, name: "", color: "", alerts: alerts, isSubmitting: false}); | ||||
|             } else { | ||||
|                 alerts.push({message: res.msg, title: "Error creating Group", type: "danger"}); | ||||
|                 this.setState({...this.state, name: "", color: "", alerts: alerts, isSubmitting: false}); | ||||
|                 this.setState({...this.state, alerts: alerts, isSubmitting: false}); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user