{% extends "base.html" %} {% block title %}{{ feed.name }} — RSS{% endblock %} {% block content %}

{{ feed.name }}

{% if feed.description %}

{{ feed.description }}

{% endif %}

{% if feed.site_url %} {# Security fix (templates audit): feed.site_url can be auto-populated from the external feed's own self-declared (rss/poller.py, "Pull site_url from the parsed feed") with no scheme check -- unlike RssItem.link/image_url, which are already run through poller.py's _is_safe_http_url() at ingest time for exactly this reason (a malicious/compromised feed publisher could set it to a javascript: URI, executed same-origin when a viewer clicks the feed's homepage link). Guarding here at render time since site_url itself wasn't covered by that ingest-time check. #} {% set _site = feed.site_url.strip() %} {% if _site.lower().startswith('http://') or _site.lower().startswith('https://') %} {{ _site }} {% else %} {{ _site }} {% endif %} {% else %} {{ feed.url }} {% endif %}

All Feeds River
{% if pagination.items %}
{% for item in pagination.items %} {% set is_unread = item.id not in read_ids %}
{% if item.image_url %} {% endif %}
{% if is_unread %} NEW {% endif %} {{ item.title or '(no title)' }}
{% if item.published_at %}{{ item.published_at|eastern('%m-%d %H:%M') }}{% else %}—{% endif %}
{% if item.summary %}

{{ item.summary[:300] }}

{% endif %}
Read {% if item.link %} Original {% endif %}
{% endfor %}
{% if pagination.pages > 1 %} {% endif %} {% else %}
No items yet. The poller fetches every ~30 minutes; if this is a fresh subscription give it a moment.
{% endif %} {% endblock %}