api_enabled) { header('HTTP/1.1 503 Service Unavailable'); header('Content-Type: text/plain; charset=UTF-8'); die('Service Unavailable!'); } FreshRSS_Context::initUser($user); if (!FreshRSS_Context::hasUserConf()) { usleep(rand(100, 10000)); //Primitive mitigation of scanning for users header('HTTP/1.1 404 Not Found'); header('Content-Type: text/plain; charset=UTF-8'); die('User not found!'); } else { usleep(rand(20, 200)); } if (!file_exists(DATA_PATH . '/no-cache.txt')) { require(LIB_PATH . '/http-conditional.php'); // TODO: Consider taking advantage of $feedMode, only for monotonous queries {all, categories, feeds} and not dynamic ones {read/unread, favourites, user labels} if (httpConditional(FreshRSS_UserDAO::mtime($user) ?: time(), 0, 0, false, PHP_COMPRESSION, false)) { exit(); //No need to send anything } } Minz_Translate::init(FreshRSS_Context::userConf()->language); Minz_ExtensionManager::init(); Minz_ExtensionManager::enableByList(FreshRSS_Context::userConf()->extensions_enabled, 'user'); $query = null; $userSearch = null; foreach (FreshRSS_Context::userConf()->queries as $raw_query) { if (!empty($raw_query['token']) && $raw_query['token'] === $token) { switch ($format) { case 'atom': case 'html': case 'rss': if (empty($raw_query['shareRss'])) { continue 2; } break; case 'opml': if (empty($raw_query['shareOpml'])) { continue 2; } break; default: continue 2; } $query = new FreshRSS_UserQuery($raw_query, FreshRSS_Context::categories(), FreshRSS_Context::labels()); Minz_Request::_param('get', $query->getGet()); if (Minz_Request::paramString('order') === '') { Minz_Request::_param('order', $query->getOrder()); } Minz_Request::_param('state', $query->getState()); $search = $query->getSearch()->getRawInput(); // Note: we disallow references to user queries in public user search to avoid sniffing internal user queries $userSearch = new FreshRSS_BooleanSearch(Minz_Request::paramString('search'), 0, 'AND', false); if ($userSearch->getRawInput() !== '') { if ($search === '') { $search = $userSearch->getRawInput(); } else { $search .= ' (' . $userSearch->getRawInput() . ')'; } } Minz_Request::_param('search', $search); break; } } if ($query === null || $userSearch === null) { usleep(rand(100, 10000)); header('HTTP/1.1 404 Not Found'); header('Content-Type: text/plain; charset=UTF-8'); die('User query not found!'); } $view = new FreshRSS_View(); try { FreshRSS_Context::updateUsingRequest(false); Minz_Request::_param('search', $userSearch->getRawInput()); // Restore user search $view->entries = FreshRSS_index_Controller::listEntriesByContext(); } catch (Minz_Exception $e) { Minz_Error::error(400, 'Bad user query!'); die(); } $get = FreshRSS_Context::currentGet(true); $type = (string)$get[0]; $id = (int)$get[1]; switch ($type) { case 'c': // Category $cat = FreshRSS_Context::categories()[$id] ?? null; if ($cat === null) { Minz_Error::error(404, "Category {$id} not found!"); die(); } $view->categories = [ $cat->id() => $cat ]; break; case 'f': // Feed $feed = FreshRSS_Category::findFeed(FreshRSS_Context::categories(), $id); if ($feed === null) { Minz_Error::error(404, "Feed {$id} not found!"); die(); } $view->feeds = [ $feed->id() => $feed ]; $view->categories = []; break; default: $view->categories = FreshRSS_Context::categories(); break; } $view->disable_aside = true; $view->excludeMutedFeeds = true; $view->internal_rendering = true; $view->userQuery = $query; $view->html_url = $query->sharedUrlHtml(); $view->rss_url = $query->sharedUrlRss(); $view->rss_title = $query->getName(); if ($query->getName() != '') { FreshRSS_View::_title($query->getName()); } FreshRSS_Context::systemConf()->allow_anonymous = true; if (in_array($format, ['rss', 'atom'], true)) { header('Content-Type: application/rss+xml; charset=utf-8'); $view->_layout(null); $view->_path('index/rss.phtml'); } elseif ($format === 'opml') { if (!$query->safeForOpml()) { Minz_Error::error(404, 'OPML not allowed for this user query!'); die(); } header('Content-Type: application/xml; charset=utf-8'); $view->_layout(null); $view->_path('index/opml.phtml'); } else { $view->_layout('layout'); $view->_path('index/html.phtml'); } $view->build();