Phase 0: stop-the-bleeding bugfixes

- Defer polling_service.start() and FilterEngine init to a one-shot
  before_request hook so importing app.py no longer spawns a scheduler
  thread (also fixes migrate_*.py import side effects).
- Fix migrate_bookmarks.py: init_db returns None, so use the shared
  `db` instead of assigning its None return.
- Enforce MIN_PASSWORD_LENGTH (8) in the password-reset route for
  consistency with signup (was hardcoded 6).
- post_detail.html: replace undefined moment(...).fromNow() (always
  "Recently") with a new timeago Jinja filter + data-timestamp attrs
  that also drive the existing JS updater; make nl2br escape-then-Markup
  and drop | safe from comment/post content to close the XSS hole.
- filter_pipeline: when AI is disabled but a filterset requires it,
  pass posts through with status=FAILED + explicit error instead of
  silently degrading to no_filter.

No source-file mojibake found; content-encoding ingest is a Phase 3 concern.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-03 01:30:13 -05:00
parent 718cc36973
commit cdba720a1c
4 changed files with 108 additions and 23 deletions

View File

@@ -31,7 +31,7 @@
<span class="post-source">{{ post.source_display if post.source_display else ('r/' + post.source if post.platform == 'reddit' else post.source) }}</span>
<span class="post-separator"></span>
{% endif %}
<span class="post-time">{{ moment(post.timestamp).fromNow() if moment else 'Recently' }}</span>
<span class="post-time" data-timestamp="{{ post.timestamp }}">{{ post.timestamp|timeago }}</span>
{% if post.url and not post.url.startswith('/') %}
<span class="external-link-indicator">🔗</span>
{% endif %}
@@ -48,7 +48,7 @@
{% if post.content %}
<div class="post-content">
{{ post.content | safe | nl2br }}
{{ post.content | nl2br }}
</div>
{% endif %}
@@ -101,10 +101,10 @@
<div class="comment-header">
<span class="comment-author">{{ comment.author }}</span>
<span class="comment-separator"></span>
<span class="comment-time">{{ moment(comment.timestamp).fromNow() if moment else 'Recently' }}</span>
<span class="comment-time" data-timestamp="{{ comment.timestamp }}">{{ comment.timestamp|timeago }}</span>
</div>
<div class="comment-content">
{{ comment.content | safe | nl2br }}
{{ comment.content | nl2br }}
</div>
<div class="comment-footer">
<div class="comment-score">