summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/autoload.php21
-rwxr-xr-xinclude/controls.php6
-rw-r--r--include/controls_compat.php302
-rw-r--r--include/errorhandler.php2
-rw-r--r--include/functions.php161
-rwxr-xr-xinclude/login_form.php2
-rwxr-xr-xinclude/sanity_check.php215
-rw-r--r--include/sessions.php66
8 files changed, 93 insertions, 682 deletions
diff --git a/include/autoload.php b/include/autoload.php
index 19e00b9ea..4422a435c 100644
--- a/include/autoload.php
+++ b/include/autoload.php
@@ -1,24 +1,17 @@
<?php
spl_autoload_register(function($class) {
- $namespace = '';
- $class_name = $class;
- if (strpos($class, '\\') !== false)
- list ($namespace, $class_name) = explode('\\', $class, 2);
+ $root_dir = dirname(__DIR__); // we were in tt-rss/include
- $root_dir = dirname(__DIR__); // we're in tt-rss/include
+ // - internal tt-rss classes are loaded from classes/ and use special naming logic instead of namespaces
+ // - plugin classes are loaded by PluginHandler from plugins.local/ and plugins/
- // 1. third party libraries with namespaces are loaded from vendor/
- // 2. internal tt-rss classes are loaded from classes/ and use special naming logic instead of namespaces
- // 3. plugin classes are loaded by PluginHandler from plugins.local/ and plugins/ (TODO: use generic autoloader?)
-
- if ($namespace && $class_name) {
- $class_file = "$root_dir/vendor/$namespace/" . str_replace('\\', '/', $class_name) . ".php";
- } else {
- $class_file = "$root_dir/classes/" . str_replace("_", "/", strtolower($class)) . ".php";
- }
+ $class_file = "$root_dir/classes/" . str_replace("_", "/", strtolower($class)) . ".php";
if (file_exists($class_file))
include $class_file;
});
+
+ // also pull composer autoloader
+ require_once "vendor/autoload.php";
diff --git a/include/controls.php b/include/controls.php
index b65a166c2..a1a1bc59b 100755
--- a/include/controls.php
+++ b/include/controls.php
@@ -2,7 +2,7 @@
namespace Controls;
function attributes_to_string(array $attributes) {
- $rv = "";
+ $rv = [];
foreach ($attributes as $k => $v) {
@@ -10,10 +10,10 @@
if ($k === "disabled" && !sql_bool_to_bool($v))
continue;
- $rv .= "$k=\"" . htmlspecialchars($v) . "\"";
+ array_push($rv, "$k=\"" . htmlspecialchars($v) . "\"");
}
- return $rv;
+ return implode(" ", $rv);
}
// shortcut syntax (disabled)
diff --git a/include/controls_compat.php b/include/controls_compat.php
index a4e9ad73f..d1c2c12b5 100644
--- a/include/controls_compat.php
+++ b/include/controls_compat.php
@@ -1,27 +1,32 @@
<?php
-function stylesheet_tag($filename, $id = false) {
- $timestamp = filemtime($filename);
+function stylesheet_tag($filename, $attributes = []) {
- $id_part = $id ? "id=\"$id\"" : "";
+ $attributes_str = \Controls\attributes_to_string(
+ array_merge(
+ [
+ "href" => "$filename?" . filemtime($filename),
+ "rel" => "stylesheet",
+ "type" => "text/css",
+ "data-orig-href" => $filename
+ ],
+ $attributes));
- return "<link rel=\"stylesheet\" $id_part type=\"text/css\" data-orig-href=\"$filename\" href=\"$filename?$timestamp\"/>\n";
+ return "<link $attributes_str/>\n";
}
-function javascript_tag($filename) {
- $query = "";
+function javascript_tag($filename, $attributes = []) {
+ $attributes_str = \Controls\attributes_to_string(
+ array_merge(
+ [
+ "src" => "$filename?" . filemtime($filename),
+ "type" => "text/javascript",
+ "charset" => "utf-8"
+ ],
+ $attributes));
- if (!(strpos($filename, "?") === false)) {
- $query = substr($filename, strpos($filename, "?")+1);
- $filename = substr($filename, 0, strpos($filename, "?"));
- }
-
- $timestamp = filemtime($filename);
-
- if ($query) $timestamp .= "&$query";
-
- return "<script type=\"text/javascript\" charset=\"utf-8\" src=\"$filename?$timestamp\"></script>\n";
+ return "<script $attributes_str></script>\n";
}
function format_warning($msg, $id = "") {
@@ -47,268 +52,3 @@ function print_warning($msg) {
function print_error($msg) {
return print format_error($msg);
}
-
-// the following is deprecated and will be eventually removed
-
-/*function print_select($id, $default, $values, $attributes = "", $name = "") {
- if (!$name) $name = $id;
-
- print "<select name=\"$name\" id=\"$id\" $attributes>";
- foreach ($values as $v) {
- if ($v == $default)
- $sel = "selected=\"1\"";
- else
- $sel = "";
-
- $v = trim($v);
-
- print "<option value=\"$v\" $sel>$v</option>";
- }
- print "</select>";
-}
-
-function print_select_hash($id, $default, $values, $attributes = "", $name = "") {
- if (!$name) $name = $id;
-
- print "<select name=\"$name\" id='$id' $attributes>";
- foreach (array_keys($values) as $v) {
- if ($v == $default)
- $sel = 'selected="selected"';
- else
- $sel = "";
-
- $v = trim($v);
-
- print "<option $sel value=\"$v\">".$values[$v]."</option>";
- }
-
- print "</select>";
-}
-
-function format_hidden($name, $value) {
- return "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"$name\" value=\"$value\">";
-}
-
-function print_hidden($name, $value) {
- print format_hidden($name, $value);
-}
-
-function format_checkbox($id, $checked, $value = "", $attributes = "") {
- $checked_str = $checked ? "checked" : "";
- $value_str = $value ? "value=\"$value\"" : "";
-
- return "<input dojoType=\"dijit.form.CheckBox\" id=\"$id\" $value_str $checked_str $attributes name=\"$id\">";
-}
-
-function print_checkbox($id, $checked, $value = "", $attributes = "") {
- print format_checkbox($id, $checked, $value, $attributes);
-}
-
-function format_button($type, $value, $attributes = "") {
- return "<button dojoType=\"dijit.form.Button\" $attributes type=\"$type\">$value</button>";
-}
-
-function print_button($type, $value, $attributes = "") {
- print format_button($type, $value, $attributes);
-}
-
-function print_feed_multi_select($id, $default_ids = [],
- $attributes = "", $include_all_feeds = true,
- $root_id = null, $nest_level = 0) {
-
- $pdo = Db::pdo();
-
- print_r(in_array("CAT:6",$default_ids));
-
- if (!$root_id) {
- print "<select multiple=\true\" id=\"$id\" name=\"$id\" $attributes>";
- if ($include_all_feeds) {
- $is_selected = (in_array("0", $default_ids)) ? "selected=\"1\"" : "";
- print "<option $is_selected value=\"0\">".__('All feeds')."</option>";
- }
- }
-
- if (get_pref(Prefs::ENABLE_FEED_CATS)) {
-
- if (!$root_id) $root_id = null;
-
- $sth = $pdo->prepare("SELECT id,title,
- (SELECT COUNT(id) FROM ttrss_feed_categories AS c2 WHERE
- c2.parent_cat = ttrss_feed_categories.id) AS num_children
- FROM ttrss_feed_categories
- WHERE owner_uid = :uid AND
- (parent_cat = :root_id OR (:root_id IS NULL AND parent_cat IS NULL)) ORDER BY title");
-
- $sth->execute([":uid" => $_SESSION['uid'], ":root_id" => $root_id]);
-
- while ($line = $sth->fetch()) {
-
- for ($i = 0; $i < $nest_level; $i++)
- $line["title"] = " " . $line["title"];
-
- $is_selected = in_array("CAT:".$line["id"], $default_ids) ? "selected=\"1\"" : "";
-
- printf("<option $is_selected value='CAT:%d'>%s</option>",
- $line["id"], htmlspecialchars($line["title"]));
-
- if ($line["num_children"] > 0)
- print_feed_multi_select($id, $default_ids, $attributes,
- $include_all_feeds, $line["id"], $nest_level+1);
-
- $f_sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
- WHERE cat_id = ? AND owner_uid = ? ORDER BY title");
-
- $f_sth->execute([$line['id'], $_SESSION['uid']]);
-
- while ($fline = $f_sth->fetch()) {
- $is_selected = (in_array($fline["id"], $default_ids)) ? "selected=\"1\"" : "";
-
- $fline["title"] = " " . $fline["title"];
-
- for ($i = 0; $i < $nest_level; $i++)
- $fline["title"] = " " . $fline["title"];
-
- printf("<option $is_selected value='%d'>%s</option>",
- $fline["id"], htmlspecialchars($fline["title"]));
- }
- }
-
- if (!$root_id) {
- $is_selected = in_array("CAT:0", $default_ids) ? "selected=\"1\"" : "";
-
- printf("<option $is_selected value='CAT:0'>%s</option>",
- __("Uncategorized"));
-
- $f_sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
- WHERE cat_id IS NULL AND owner_uid = ? ORDER BY title");
- $f_sth->execute([$_SESSION['uid']]);
-
- while ($fline = $f_sth->fetch()) {
- $is_selected = in_array($fline["id"], $default_ids) ? "selected=\"1\"" : "";
-
- $fline["title"] = " " . $fline["title"];
-
- for ($i = 0; $i < $nest_level; $i++)
- $fline["title"] = " " . $fline["title"];
-
- printf("<option $is_selected value='%d'>%s</option>",
- $fline["id"], htmlspecialchars($fline["title"]));
- }
- }
-
- } else {
- $sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
- WHERE owner_uid = ? ORDER BY title");
- $sth->execute([$_SESSION['uid']]);
-
- while ($line = $sth->fetch()) {
-
- $is_selected = (in_array($line["id"], $default_ids)) ? "selected=\"1\"" : "";
-
- printf("<option $is_selected value='%d'>%s</option>",
- $line["id"], htmlspecialchars($line["title"]));
- }
- }
-
- if (!$root_id) {
- print "</select>";
- }
-}
-
-function print_feed_cat_select($id, $default_id, $attributes, $include_all_cats = true,
- $root_id = null, $nest_level = 0) {
-
- print format_feed_cat_select($id, $default_id, $attributes, $include_all_cats, $root_id, $nest_level);
-}
-
-function format_feed_cat_select($id, $default_id, $attributes, $include_all_cats = true,
- $root_id = null, $nest_level = 0) {
-
- $ret = "";
-
- if (!$root_id) {
- $ret .= "<select id=\"$id\" name=\"$id\" default=\"$default_id\" $attributes>";
- }
-
- $pdo = Db::pdo();
-
- if (!$root_id) $root_id = null;
-
- $sth = $pdo->prepare("SELECT id,title,
- (SELECT COUNT(id) FROM ttrss_feed_categories AS c2 WHERE
- c2.parent_cat = ttrss_feed_categories.id) AS num_children
- FROM ttrss_feed_categories
- WHERE owner_uid = :uid AND
- (parent_cat = :root_id OR (:root_id IS NULL AND parent_cat IS NULL)) ORDER BY title");
- $sth->execute([":uid" => $_SESSION['uid'], ":root_id" => $root_id]);
-
- $found = 0;
-
- while ($line = $sth->fetch()) {
- ++$found;
-
- if ($line["id"] == $default_id) {
- $is_selected = "selected=\"1\"";
- } else {
- $is_selected = "";
- }
-
- for ($i = 0; $i < $nest_level; $i++)
- $line["title"] = " " . $line["title"];
-
- if ($line["title"])
- $ret .= sprintf("<option $is_selected value='%d'>%s</option>",
- $line["id"], htmlspecialchars($line["title"]));
-
- if ($line["num_children"] > 0)
- $ret .= format_feed_cat_select($id, $default_id, $attributes,
- $include_all_cats, $line["id"], $nest_level+1);
- }
-
- if (!$root_id) {
- if ($include_all_cats) {
- if ($found > 0) {
- $ret .= "<option disabled=\"1\">―――――――――――――――</option>";
- }
-
- if ($default_id == 0) {
- $is_selected = "selected=\"1\"";
- } else {
- $is_selected = "";
- }
-
- $ret .= "<option $is_selected value=\"0\">".__('Uncategorized')."</option>";
- }
- $ret .= "</select>";
- }
-
- return $ret;
-}
-
-function print_label_select($name, $value, $attributes = "") {
-
- $pdo = Db::pdo();
-
- $sth = $pdo->prepare("SELECT caption FROM ttrss_labels2
- WHERE owner_uid = ? ORDER BY caption");
- $sth->execute([$_SESSION['uid']]);
-
- print "<select default=\"$value\" name=\"" . htmlspecialchars($name) .
- "\" $attributes>";
-
- while ($line = $sth->fetch()) {
-
- $issel = ($line["caption"] == $value) ? "selected=\"1\"" : "";
-
- print "<option value=\"".htmlspecialchars($line["caption"])."\"
- $issel>" . htmlspecialchars($line["caption"]) . "</option>";
-
- }
-
-# print "<option value=\"ADD_LABEL\">" .__("Add label...") . "</option>";
-
- print "</select>";
-
-
-}
-*/
diff --git a/include/errorhandler.php b/include/errorhandler.php
index 1908bd39c..2ad0be062 100644
--- a/include/errorhandler.php
+++ b/include/errorhandler.php
@@ -55,6 +55,8 @@ function ttrss_error_handler($errno, $errstr, $file, $line) {
if (class_exists("Logger"))
return Logger::log_error((int)$errno, $errstr, $file, (int)$line, $context);
+ else
+ return false;
}
function ttrss_fatal_handler() {
diff --git a/include/functions.php b/include/functions.php
index e0580a076..73d963803 100644
--- a/include/functions.php
+++ b/include/functions.php
@@ -1,15 +1,9 @@
<?php
- define('SCHEMA_VERSION', 141);
-
define('LABEL_BASE_INDEX', -1024);
define('PLUGIN_FEED_BASE_INDEX', -128);
- $fetch_last_error = false;
- $fetch_last_error_code = false;
- $fetch_last_content_type = false;
- $fetch_last_error_content = false; // curl only for the time being
- $fetch_effective_url = false;
- $fetch_curl_used = false;
+ /** constant is @deprecated, use Config::SCHEMA_VERSION instead */
+ define('SCHEMA_VERSION', Config::SCHEMA_VERSION);
if (version_compare(PHP_VERSION, '8.0.0', '<')) {
libxml_disable_entity_loader(true);
@@ -163,73 +157,74 @@
require_once 'controls.php';
require_once 'controls_compat.php';
- define('SELF_USER_AGENT', 'Tiny Tiny RSS/' . get_version() . ' (http://tt-rss.org/)');
+ define('SELF_USER_AGENT', 'Tiny Tiny RSS/' . Config::get_version() . ' (http://tt-rss.org/)');
ini_set('user_agent', SELF_USER_AGENT);
/* compat shims */
+ /** function is @deprecated */
+ function get_version() {
+ return Config::get_version();
+ }
+
+ /** function is @deprecated */
+ function get_schema_version() {
+ return Config::get_schema_version();
+ }
+
+ /** function is @deprecated */
function _debug($msg) {
Debug::log($msg);
}
- // @deprecated
+ /** function is @deprecated */
function getFeedUnread($feed, $is_cat = false) {
return Feeds::_get_counters($feed, $is_cat, true, $_SESSION["uid"]);
}
- // @deprecated
+ /** function is @deprecated */
function sanitize($str, $force_remove_images = false, $owner = false, $site_url = false, $highlight_words = false, $article_id = false) {
return Sanitizer::sanitize($str, $force_remove_images, $owner, $site_url, $highlight_words, $article_id);
}
- // @deprecated
+ /** function is @deprecated */
function fetch_file_contents($params) {
return UrlHelper::fetch($params);
}
- // @deprecated
+ /** function is @deprecated */
function rewrite_relative_url($url, $rel_url) {
return UrlHelper::rewrite_relative($url, $rel_url);
}
- // @deprecated
+ /** function is @deprecated */
function validate_url($url) {
return UrlHelper::validate($url);
}
- // @deprecated
+ /** function is @deprecated */
function authenticate_user($login, $password, $check_only = false, $service = false) {
return UserHelper::authenticate($login, $password, $check_only, $service);
}
- // @deprecated
+ /** function is @deprecated */
function smart_date_time($timestamp, $tz_offset = 0, $owner_uid = false, $eta_min = false) {
return TimeHelper::smart_date_time($timestamp, $tz_offset, $owner_uid, $eta_min);
}
- // @deprecated
+ /** function is @deprecated */
function make_local_datetime($timestamp, $long, $owner_uid = false, $no_smart_dt = false, $eta_min = false) {
return TimeHelper::make_local_datetime($timestamp, $long, $owner_uid, $no_smart_dt, $eta_min);
}
- /* end compat shims */
-
- function get_ssl_certificate_id() {
- if ($_SERVER["REDIRECT_SSL_CLIENT_M_SERIAL"] ?? false) {
- return sha1($_SERVER["REDIRECT_SSL_CLIENT_M_SERIAL"] .
- $_SERVER["REDIRECT_SSL_CLIENT_V_START"] .
- $_SERVER["REDIRECT_SSL_CLIENT_V_END"] .
- $_SERVER["REDIRECT_SSL_CLIENT_S_DN"]);
- }
- if ($_SERVER["SSL_CLIENT_M_SERIAL"] ?? false) {
- return sha1($_SERVER["SSL_CLIENT_M_SERIAL"] .
- $_SERVER["SSL_CLIENT_V_START"] .
- $_SERVER["SSL_CLIENT_V_END"] .
- $_SERVER["SSL_CLIENT_S_DN"]);
- }
- return "";
+ // this returns Config::SELF_URL_PATH sans ending slash
+ /** function is @deprecated by Config::get_self_url() */
+ function get_self_url_prefix() {
+ return Config::get_self_url();
}
+ /* end compat shims */
+
// this is used for user http parameters unless HTML code is actually needed
function clean($param) {
if (is_array($param)) {
@@ -241,6 +236,14 @@
}
}
+ function with_trailing_slash(string $str) : string {
+ if (substr($str, -1) === "/") {
+ return $str;
+ } else {
+ return "$str/";
+ }
+ }
+
function make_password($length = 12) {
$password = "";
$possible = "0123456789abcdfghjkmnpqrstvwxyzABCDFGHJKMNPQRSTVWXYZ*%+^";
@@ -303,10 +306,6 @@
return $s ? 1 : 0;
}
- function get_schema_version() {
- return Config::get_schema_version();
- }
-
function file_is_locked($filename) {
if (file_exists(Config::get(Config::LOCK_DIRECTORY) . "/$filename")) {
if (function_exists('flock')) {
@@ -371,34 +370,6 @@
return vsprintf(_ngettext(array_shift($args), array_shift($args), array_shift($args)), $args);
}
- function is_server_https() {
- return (!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] != 'off')) ||
- (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https');
- }
-
- function is_prefix_https() {
- return parse_url(Config::get(Config::SELF_URL_PATH), PHP_URL_SCHEME) == 'https';
- }
-
- // this returns Config::get(Config::SELF_URL_PATH) sans ending slash
- function get_self_url_prefix() {
- if (strrpos(Config::get(Config::SELF_URL_PATH), "/") === strlen(Config::get(Config::SELF_URL_PATH))-1) {
- return substr(Config::get(Config::SELF_URL_PATH), 0, strlen(Config::get(Config::SELF_URL_PATH))-1);
- } else {
- return Config::get(Config::SELF_URL_PATH);
- }
- }
-
- function encrypt_password($pass, $salt = '', $mode2 = false) {
- if ($salt && $mode2) {
- return "MODE2:" . hash('sha256', $salt . $pass);
- } else if ($salt) {
- return "SHA1X:" . sha1("$salt:$pass");
- } else {
- return "SHA1:" . sha1($pass);
- }
- } // function encrypt_password
-
function init_plugins() {
PluginHost::getInstance()->load(Config::get(Config::PLUGINS), PluginHost::KIND_ALL);
@@ -471,63 +442,3 @@
return $ts;
}
- /* for package maintainers who don't use git: if version_static.txt exists in tt-rss root
- directory, its contents are displayed instead of git commit-based version, this could be generated
- based on source git tree commit used when creating the package */
-
- function get_version(&$git_commit = false, &$git_timestamp = false, &$last_error = false) {
- global $ttrss_version;
-
- if (is_array($ttrss_version) && isset($ttrss_version['version'])) {
- $git_commit = $ttrss_version['commit'];
- $git_timestamp = $ttrss_version['timestamp'];
- $last_error = $ttrss_version['last_error'] ?? "";
-
- return $ttrss_version['version'];
- } else {
- $ttrss_version = [];
- }
-
- $ttrss_version['version'] = "UNKNOWN (Unsupported)";
-
- date_default_timezone_set('UTC');
- $root_dir = dirname(__DIR__);
-
- if (PHP_OS === "Darwin") {
- $ttrss_version['version'] = "UNKNOWN (Unsupported, Darwin)";
- } else if (file_exists("$root_dir/version_static.txt")) {
- $ttrss_version['version'] = trim(file_get_contents("$root_dir/version_static.txt")) . " (Unsupported)";
- } else if (is_dir("$root_dir/.git")) {
- $rc = 0;
- $output = [];
-
- $cwd = getcwd();
-
- chdir($root_dir);
- exec('git --no-pager log --pretty="version: %ct %h" -n1 HEAD 2>&1', $output, $rc);
- chdir($cwd);
-
- if (is_array($output) && count($output) > 0) {
- list ($test, $timestamp, $commit) = explode(" ", $output[0], 3);
-
- if ($test == "version:") {
- $git_commit = $commit;
- $git_timestamp = $timestamp;
-
- $ttrss_version['version'] = strftime("%y.%m", (int)$timestamp) . "-$commit";
- $ttrss_version['commit'] = $commit;
- $ttrss_version['timestamp'] = $timestamp;
- }
- }
-
- if (!isset($ttrss_version['commit'])) {
- $last_error = "Unable to determine version (using $root_dir): RC=$rc; OUTPUT=" . implode("\n", $output);
-
- $ttrss_version["last_error"] = $last_error;
-
- user_error($last_error, E_USER_WARNING);
- }
- }
-
- return $ttrss_version['version'];
- }
diff --git a/include/login_form.php b/include/login_form.php
index 06bf57470..9efe0e238 100755
--- a/include/login_form.php
+++ b/include/login_form.php
@@ -85,7 +85,7 @@
</script>
-<?php $return = urlencode(make_self_url()) ?>
+<?php $return = urlencode(!empty($_REQUEST['return']) ? $_REQUEST['return'] : with_trailing_slash(Config::make_self_url())) ?>
<div class="container">
diff --git a/include/sanity_check.php b/include/sanity_check.php
deleted file mode 100755
index 4831209ba..000000000
--- a/include/sanity_check.php
+++ /dev/null
@@ -1,215 +0,0 @@
-<?php
- /* WARNING! If you modify this file, you are ON YOUR OWN! */
-
- function make_self_url() {
- $proto = is_server_https() ? 'https' : 'http';
-
- return $proto . '://' . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
- }
-
- function make_self_url_path() {
- if (!isset($_SERVER["HTTP_HOST"])) return false;
-
- $proto = is_server_https() ? 'https' : 'http';
- $url_path = $proto . '://' . $_SERVER["HTTP_HOST"] . parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
-
- return $url_path;
- }
-
- function check_mysql_tables() {
- $pdo = Db::pdo();
-
- $sth = $pdo->prepare("SELECT engine, table_name FROM information_schema.tables WHERE
- table_schema = ? AND table_name LIKE 'ttrss_%' AND engine != 'InnoDB'");
- $sth->execute([Config::get(Config::DB_NAME)]);
-
- $bad_tables = [];
-
- while ($line = $sth->fetch()) {
- array_push($bad_tables, $line);
- }
-
- return $bad_tables;
- }
-
- function initial_sanity_check() {
-
- $errors = array();
-
- if (!file_exists("config.php")) {
- array_push($errors, "Configuration file not found. Looks like you forgot to copy config.php-dist to config.php and edit it.");
- } else {
-
- if (!file_exists("config.php")) {
- array_push($errors, "Please copy config.php-dist to config.php");
- }
-
- if (strpos(Config::get(Config::PLUGINS), "auth_") === false) {
- array_push($errors, "Please enable at least one authentication module via Config::get(Config::PLUGINS) constant in config.php");
- }
-
- if (function_exists('posix_getuid') && posix_getuid() == 0) {
- array_push($errors, "Please don't run this script as root.");
- }
-
- if (version_compare(PHP_VERSION, '7.0.0', '<')) {
- array_push($errors, "PHP version 7.0.0 or newer required. You're using " . PHP_VERSION . ".");
- }
-
- if (!class_exists("UConverter")) {
- array_push($errors, "PHP UConverter class is missing, it's provided by the Internationalization (intl) module.");
- }
-
- if (!is_writable(Config::get(Config::CACHE_DIR) . "/images")) {
- array_push($errors, "Image cache is not writable (chmod -R 777 ".Config::get(Config::CACHE_DIR)."/images)");
- }
-
- if (!is_writable(Config::get(Config::CACHE_DIR) . "/upload")) {
- array_push($errors, "Upload cache is not writable (chmod -R 777 ".Config::get(Config::CACHE_DIR)."/upload)");
- }
-
- if (!is_writable(Config::get(Config::CACHE_DIR) . "/export")) {
- array_push($errors, "Data export cache is not writable (chmod -R 777 ".Config::get(Config::CACHE_DIR)."/export)");
- }
-
- if (Config::get(Config::SINGLE_USER_MODE) && class_exists("PDO")) {
- $pdo = Db::pdo();
-
- $res = $pdo->query("SELECT id FROM ttrss_users WHERE id = 1");
-
- if (!$res->fetch()) {
- array_push($errors, "Config::get(Config::SINGLE_USER_MODE) is enabled in config.php but default admin account is not found.");
- }
- }
-
- if (php_sapi_name() != "cli") {
- $ref_self_url_path = make_self_url_path();
-
- if ($ref_self_url_path) {
- $ref_self_url_path = preg_replace("/\w+\.php$/", "", $ref_self_url_path);
- }
-
- if (Config::get(Config::SELF_URL_PATH) == "http://example.org/tt-rss/") {
- $hint = $ref_self_url_path ? "(possible value: <b>$ref_self_url_path</b>)" : "";
- array_push($errors,
- "Please set Config::get(Config::SELF_URL_PATH) to the correct value for your server: $hint");
- }
-
- if ($ref_self_url_path &&
- (!defined('_SKIP_SELF_URL_PATH_CHECKS') || !_SKIP_SELF_URL_PATH_CHECKS) &&
- Config::get(Config::SELF_URL_PATH) != $ref_self_url_path && Config::get(Config::SELF_URL_PATH) != mb_substr($ref_self_url_path, 0, mb_strlen($ref_self_url_path)-1)) {
- array_push($errors,
- "Please set Config::get(Config::SELF_URL_PATH) to the correct value detected for your server: <b>$ref_self_url_path</b> (you're using: <b>" . Config::get(Config::SELF_URL_PATH) . "</b>)");
- }
- }
-
- if (!is_writable(Config::get(Config::ICONS_DIR))) {
- array_push($errors, "ICONS_DIR defined in config.php is not writable (chmod -R 777 ".Config::get(Config::ICONS_DIR).").\n");
- }
-
- if (!is_writable(Config::get(Config::LOCK_DIRECTORY))) {
- array_push($errors, "Config::get(Config::LOCK_DIRECTORY) defined in config.php is not writable (chmod -R 777 ".Config::get(Config::LOCK_DIRECTORY).").\n");
- }
-
- if (!function_exists("curl_init") && !ini_get("allow_url_fopen")) {
- array_push($errors, "PHP configuration option allow_url_fopen is disabled, and CURL functions are not present. Either enable allow_url_fopen or install PHP extension for CURL.");
- }
-
- if (!function_exists("json_encode")) {
- array_push($errors, "PHP support for JSON is required, but was not found.");
- }
-
- if (!class_exists("PDO")) {
- array_push($errors, "PHP support for PDO is required but was not found.");
- }
-
- if (!function_exists("mb_strlen")) {
- array_push($errors, "PHP support for mbstring functions is required but was not found.");
- }
-
- if (!function_exists("hash")) {
- array_push($errors, "PHP support for hash() function is required but was not found.");
- }
-
- if (ini_get("safe_mode")) {
- array_push($errors, "PHP safe mode setting is obsolete and not supported by tt-rss.");
- }
-
- if (!function_exists("mime_content_type")) {
- array_push($errors, "PHP function mime_content_type() is missing, try enabling fileinfo module.");
- }
-
- if (!class_exists("DOMDocument")) {
- array_push($errors, "PHP support for DOMDocument is required, but was not found.");
- }
-
- if (Config::get(Config::DB_TYPE) == "mysql") {
- $bad_tables = check_mysql_tables();
-
- if (count($bad_tables) > 0) {
- $bad_tables_fmt = [];
-
- foreach ($bad_tables as $bt) {
- array_push($bad_tables_fmt, sprintf("%s (%s)", $bt['table_name'], $bt['engine']));
- }
-
- $msg = "<p>The following tables use an unsupported MySQL engine: <b>" .
- implode(", ", $bad_tables_fmt) . "</b>.</p>";
-
- $msg .= "<p>The only supported engine on MySQL is InnoDB. MyISAM lacks functionality to run
- tt-rss.
- Please backup your data (via OPML) and re-import the schema before continuing.</p>
- <p><b>WARNING: importing the schema would mean LOSS OF ALL YOUR DATA.</b></p>";
-
-
- array_push($errors, $msg);
- }
- }
- }
-
- if (count($errors) > 0 && php_sapi_name() != "cli") { ?>
- <!DOCTYPE html>
- <html>
- <head>
- <title>Startup failed</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <link rel="stylesheet" type="text/css" href="themes/light.css">
- </head>
- <body class='sanity_failed claro ttrss_utility'>
- <div class="content">
-
- <h1>Startup failed</h1>
-
- <p>Tiny Tiny RSS was unable to start properly. This usually means a misconfiguration or an incomplete upgrade. Please fix
- errors indicated by the following messages:</p>
-
- <?php foreach ($errors as $error) { echo format_error($error); } ?>
-
- <p>You might want to check tt-rss <a href="https://tt-rss.org/wiki.php">wiki</a> or the
- <a href="https://community.tt-rss.org/">forums</a> for more information. Please search the forums before creating new topic
- for your question.</p>
-
- </div>
- </body>
- </html>
-
- <?php
- die;
- } else if (count($errors) > 0) {
- echo "Tiny Tiny RSS was unable to start properly. This usually means a misconfiguration or an incomplete upgrade.\n";
- echo "Please fix errors indicated by the following messages:\n\n";
-
- foreach ($errors as $error) {
- echo " * " . strip_tags($error)."\n";
- }
-
- echo "\nYou might want to check tt-rss wiki or the forums for more information.\n";
- echo "Please search the forums before creating new topic for your question.\n";
-
- exit(-1);
- }
- }
-
- initial_sanity_check();
-
-?>
diff --git a/include/sessions.php b/include/sessions.php
index 891a6b3fa..9044c609b 100644
--- a/include/sessions.php
+++ b/include/sessions.php
@@ -9,7 +9,7 @@
$session_expire = min(2147483647 - time() - 1, max(\Config::get(\Config::SESSION_COOKIE_LIFETIME), 86400));
$session_name = \Config::get(\Config::SESSION_NAME);
- if (is_server_https()) {
+ if (\Config::is_server_https()) {
ini_set("session.cookie_secure", "true");
}
@@ -22,41 +22,19 @@
function validate_session() {
if (\Config::get(\Config::SINGLE_USER_MODE)) return true;
- if (isset($_SESSION["ref_schema_version"]) && $_SESSION["ref_schema_version"] != \Config::get_schema_version()) {
- $_SESSION["login_error_msg"] =
- __("Session failed to validate (schema version changed)");
- return false;
- }
- $pdo = \Db::pdo();
+ $pdo = \Db::pdo();
if (!empty($_SESSION["uid"])) {
+ $user = \ORM::for_table('ttrss_users')->find_one($_SESSION["uid"]);
- if ($_SESSION["user_agent"] != sha1($_SERVER['HTTP_USER_AGENT'])) {
- $_SESSION["login_error_msg"] = __("Session failed to validate (UA changed).");
- return false;
- }
-
- $sth = $pdo->prepare("SELECT pwd_hash FROM ttrss_users WHERE id = ?");
- $sth->execute([$_SESSION['uid']]);
-
- // user not found
- if ($row = $sth->fetch()) {
- $pwd_hash = $row["pwd_hash"];
-
- if ($pwd_hash != $_SESSION["pwd_hash"]) {
-
- $_SESSION["login_error_msg"] =
- __("Session failed to validate (password changed)");
-
- return false;
- }
+ if ($user) {
+ if ($user->pwd_hash != $_SESSION["pwd_hash"]) {
+ $_SESSION["login_error_msg"] = __("Session failed to validate (password changed)");
+ return false;
+ }
} else {
-
- $_SESSION["login_error_msg"] =
- __("Session failed to validate (user not found)");
-
- return false;
-
+ $_SESSION["login_error_msg"] = __("Session failed to validate (user not found)");
+ return false;
}
}
@@ -127,17 +105,19 @@
return true;
}
- if (!\Config::get(\Config::SINGLE_USER_MODE)) {
- session_set_save_handler('\Sessions\ttrss_open',
- '\Sessions\ttrss_close', '\Sessions\ttrss_read',
- '\Sessions\ttrss_write', '\Sessions\ttrss_destroy',
- '\Sessions\ttrss_gc');
- register_shutdown_function('session_write_close');
- }
+ if (\Config::get_schema_version() >= 0) {
+ if (!\Config::get(\Config::SINGLE_USER_MODE)) {
+ session_set_save_handler('\Sessions\ttrss_open',
+ '\Sessions\ttrss_close', '\Sessions\ttrss_read',
+ '\Sessions\ttrss_write', '\Sessions\ttrss_destroy',
+ '\Sessions\ttrss_gc');
+ register_shutdown_function('session_write_close');
+ }
- if (!defined('NO_SESSION_AUTOSTART')) {
- if (isset($_COOKIE[session_name()])) {
- if (session_status() != PHP_SESSION_ACTIVE)
- session_start();
+ if (!defined('NO_SESSION_AUTOSTART')) {
+ if (isset($_COOKIE[session_name()])) {
+ if (session_status() != PHP_SESSION_ACTIVE)
+ session_start();
+ }
}
}