if (!SINGLE_USER_MODE) {
$user_id = false;
+ $auth_module = false;
foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_AUTH_USER) as $plugin) {
$user_id = (int) $plugin->authenticate($login, $password);
if ($user_id) {
- $_SESSION["auth_module"] = strtolower(get_class($plugin));
+ $auth_module = strtolower(get_class($plugin));
break;
}
}
if ($user_id && !$check_only) {
- @session_start();
+
+ session_start();
+ session_regenerate_id(true);
$_SESSION["uid"] = $user_id;
$_SESSION["version"] = VERSION_STATIC;
+ $_SESSION["auth_module"] = $auth_module;
$pdo = DB::pdo();
$sth = $pdo->prepare("SELECT login,access_level,pwd_hash FROM ttrss_users
}
function logout_user() {
- session_destroy();
+ @session_destroy();
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time()-42000, '/');
}
+ session_commit();
}
function validate_csrf($csrf_token) {
}
if (!$_SESSION["uid"]) {
- @session_destroy();
- setcookie(session_name(), '', time()-42000, '/');
+ logout_user();
render_login_form();
exit;
return false;
}
- function sanitize($str, $force_remove_images = false, $owner = false, $site_url = false, $highlight_words = false, $article_id = false) {
- if (!$owner) $owner = $_SESSION["uid"];
-
- $res = trim($str); if (!$res) return '';
+ // check for locally cached (media) URLs and rewrite to local versions
+ // this is called separately after sanitize() and plugin render article hooks to allow
+ // plugins work on original source URLs used before caching
+ function rewrite_cached_urls($str) {
$charset_hack = '<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>';
- $res = trim($res); if (!$res) return '';
-
- libxml_use_internal_errors(true);
+ $res = trim($str); if (!$res) return '';
$doc = new DOMDocument();
$doc->loadHTML($charset_hack . $res);
$xpath = new DOMXPath($doc);
- $rewrite_base_url = $site_url ? $site_url : get_self_url_prefix();
+ $entries = $xpath->query('(//img[@src]|//video[@poster]|//video/source[@src]|//audio/source[@src])');
- $entries = $xpath->query('(//a[@href]|//img[@src]|//video/source[@src]|//audio/source[@src])');
+ $need_saving = false;
foreach ($entries as $entry) {
- if ($entry->hasAttribute('href')) {
- $entry->setAttribute('href',
- rewrite_relative_url($rewrite_base_url, $entry->getAttribute('href')));
+ if ($entry->hasAttribute('src') || $entry->hasAttribute('poster')) {
- $entry->setAttribute('rel', 'noopener noreferrer');
- }
-
- if ($entry->hasAttribute('src')) {
- $src = rewrite_relative_url($rewrite_base_url, $entry->getAttribute('src'));
+ // should be already absolutized because this is called after sanitize()
+ $src = $entry->hasAttribute('poster') ? $entry->getAttribute('poster') : $entry->getAttribute('src');
$cached_filename = CACHE_DIR . '/images/' . sha1($src);
if (file_exists($cached_filename)) {
$src = get_self_url_prefix() . '/public.php?op=cached_url&hash=' . sha1($src) . $suffix;
- if ($entry->hasAttribute('srcset')) {
- $entry->removeAttribute('srcset');
- }
+ if ($entry->hasAttribute('poster'))
+ $entry->setAttribute('poster', $src);
+ else
+ $entry->setAttribute('src', $src);
- if ($entry->hasAttribute('sizes')) {
- $entry->removeAttribute('sizes');
- }
+ $need_saving = true;
}
+ }
+ }
+
+ if ($need_saving) {
+ $doc->removeChild($doc->firstChild); //remove doctype
+ $res = $doc->saveHTML();
+ }
+
+ return $res;
+ }
+
+ function sanitize($str, $force_remove_images = false, $owner = false, $site_url = false, $highlight_words = false, $article_id = false) {
+ if (!$owner) $owner = $_SESSION["uid"];
+
+ $res = trim($str); if (!$res) return '';
+
+ $charset_hack = '<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ </head>';
+
+ $res = trim($res); if (!$res) return '';
+
+ libxml_use_internal_errors(true);
+
+ $doc = new DOMDocument();
+ $doc->loadHTML($charset_hack . $res);
+ $xpath = new DOMXPath($doc);
+
+ $rewrite_base_url = $site_url ? $site_url : get_self_url_prefix();
+
+ $entries = $xpath->query('(//a[@href]|//img[@src]|//video/source[@src]|//audio/source[@src])');
+
+ foreach ($entries as $entry) {
+
+ if ($entry->hasAttribute('href')) {
+ $entry->setAttribute('href',
+ rewrite_relative_url($rewrite_base_url, $entry->getAttribute('href')));
+
+ $entry->setAttribute('rel', 'noopener noreferrer');
+ }
+
+ if ($entry->hasAttribute('src')) {
+ $src = rewrite_relative_url($rewrite_base_url, $entry->getAttribute('src'));
+
+ // cache stuff has gone to rewrite_cached_urls()
$entry->setAttribute('src', $src);
}
}
}
}
+ }
+
+ if ($entry->hasAttribute('src') &&
+ ($owner && get_pref("STRIP_IMAGES", $owner)) || $force_remove_images || $_SESSION["bw_limit"]) {
- if (($owner && get_pref("STRIP_IMAGES", $owner)) ||
- $force_remove_images || $_SESSION["bw_limit"]) {
+ $p = $doc->createElement('p');
- $p = $doc->createElement('p');
+ $a = $doc->createElement('a');
+ $a->setAttribute('href', $entry->getAttribute('src'));
- $a = $doc->createElement('a');
- $a->setAttribute('href', $entry->getAttribute('src'));
+ $a->appendChild(new DOMText($entry->getAttribute('src')));
+ $a->setAttribute('target', '_blank');
+ $a->setAttribute('rel', 'noopener noreferrer');
- $a->appendChild(new DOMText($entry->getAttribute('src')));
- $a->setAttribute('target', '_blank');
- $a->setAttribute('rel', 'noopener noreferrer');
+ $p->appendChild($a);
- $p->appendChild($a);
+ if ($entry->nodeName == 'source') {
+
+ if ($entry->parentNode && $entry->parentNode->parentNode)
+ $entry->parentNode->parentNode->replaceChild($p, $entry->parentNode);
+
+ } else if ($entry->nodeName == 'img') {
+
+ if ($entry->parentNode)
+ $entry->parentNode->replaceChild($p, $entry);
- $entry->parentNode->replaceChild($p, $entry);
}
}
}
function get_minified_js($files) {
- require_once 'lib/jshrink/Minifier.php';
$rv = '';
should be loaded systemwide in config.php */
function send_local_file($filename) {
if (file_exists($filename)) {
+
+ if (is_writable($filename)) touch($filename);
+
$tmppluginhost = new PluginHost();
$tmppluginhost->load(PLUGINS, PluginHost::KIND_SYSTEM);
}
$mimetype = mime_content_type($filename);
+
+ // this is hardly ideal but 1) only media is cached in images/ and 2) seemingly only mp4
+ // video files are detected as octet-stream by mime_content_type()
+
+ if ($mimetype == "application/octet-stream")
+ $mimetype = "video/mp4";
+
header("Content-type: $mimetype");
$stamp = gmdate("D, d M Y H:i:s", filemtime($filename)) . " GMT";