Ignore:
Timestamp:
07/01/2026 07:26:13 PM (2 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
9e1b1bb
Parents:
1c2dcba
Message:

feat(fediverse): receive reports (inbound Flag) → owner's notifications

Completes the Klonkt↔Klonkt report loop: a Flag delivered to a Klonkt inbox was
previously ignored. It's now signature-enforced, stored, and surfaced to the site
owner (who moderates their own instance) in the fediverse notifications.

  • src/config/database.js — ap_reports table (per-site incoming reports).
  • src/services/ActivityPubService.js — handleInbox handles inbound Flag (resolves which local site it targets from the reported object URIs, stores reporter + reason); Flag added to the signature-GATED list; getNotifications includes reports.
  • src/views/pages/fedi-notifications.ejs — a report item (flag icon, reason).
  • src/services/i18n.js — notif.reported (nl/en/de).
  • CHANGELOG(.nl/.de).md — note that reports about your site show in notifications.

Co-Authored-By: Claude <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/views/pages/fedi-notifications.ejs

    r1c2dcba r737ea05  
    77    <ul class="nt-list">
    88      <% items.forEach(function(n){
    9            var _ic = n.type === 'follow' ? 'follow' : (n.type === 'like' ? 'like' : (n.type === 'announce' ? 'boost' : 'reply'));
     9           var _ic = n.type === 'follow' ? 'follow' : (n.type === 'like' ? 'like' : (n.type === 'announce' ? 'boost' : (n.type === 'report' ? 'report' : 'reply')));
    1010      %>
    1111        <li class="nt-item nt-<%= _ic %>">
     
    1414            <% } else if (_ic === 'boost') { %><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="17 1 21 5 17 9"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><polyline points="7 23 3 19 7 15"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/></svg>
    1515            <% } else if (_ic === 'follow') { %><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><line x1="19" y1="8" x2="19" y2="14"/><line x1="22" y1="11" x2="16" y2="11"/></svg>
     16            <% } else if (_ic === 'report') { %><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><line x1="4" y1="22" x2="4" y2="15"/></svg>
    1617            <% } else { %><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg><% } %>
    1718          </span>
     
    2627              <% } else if (n.type === 'like') { %><%= t('notif.liked') %>
    2728              <% } else if (n.type === 'announce') { %><%= t('notif.boosted') %>
     29              <% } else if (n.type === 'report') { %><%= t('notif.reported') %>
    2830              <% } else { %><%= t('notif.replied') %><% } %>
    2931              <% if (n.post_slug) { %><a class="nt-post" href="/<%= n.post_slug %>"><%= n.post_title || n.post_slug %></a><% } %>
    3032            </div>
    31             <% if (n.type === 'reply' && n.content) { %><div class="nt-content"><%- n.content %></div><% } %>
     33            <% if (n.type === 'report' && n.content) { %><div class="nt-content"><%= n.content %></div>
     34            <% } else if (n.type === 'reply' && n.content) { %><div class="nt-content"><%- n.content %></div><% } %>
    3235          </div>
    3336        </li>
     
    5558  .nt-boost .nt-icon { background: color-mix(in srgb, #2fa85a 16%, transparent); color: #2fa85a; }
    5659  .nt-follow .nt-icon, .nt-reply .nt-icon { background: color-mix(in srgb, var(--accent, #888) 16%, transparent); color: var(--accent, #06c); }
     60  .nt-report .nt-icon { background: color-mix(in srgb, #c0392b 16%, transparent); color: #c0392b; }
    5761  .nt-body { flex: 1; min-width: 0; }
    5862  .nt-line { display: flex; align-items: baseline; gap: .4rem; }
Note: See TracChangeset for help on using the changeset viewer.