Changeset 1c2dcba in Klonkt


Ignore:
Timestamp:
07/01/2026 07:14:12 PM (2 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
737ea05
Parents:
0688b5f
Message:

feat(fediverse): report a post/account to its home server (AS2 Flag)

From the interact page you can now report a fediverse post to its home server's
moderators. Sends the Mastodon-standard AS2 Flag (object = [reported account,
reported status], content = the reason) to the reported account's inbox.

  • src/services/ActivityPubService.js — sendReport(site, {objectUri, actorUri, reason}) resolves the reported account, builds the Flag and delivers it to their inbox.
  • src/routes/posts.js — POST /authorize_interaction/report (owner-only); GET passes reported and skips re-resolving on the confirmation view.
  • src/views/pages/authorize-interaction.ejs — a "Report this post" disclosure with a reason field, a "reported" confirmation, and scoped styles.
  • src/services/i18n.js — fedi.report_* + fedi.reported_* (nl/en/de).
  • test/activitypub-as2.test.js — allow the AS2 Flag activity type.
  • CHANGELOG(.nl/.de).md — "Report a post to the fediverse" under Unreleased.

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

Files:
8 edited

Legend:

Unmodified
Added
Removed
  • CHANGELOG.de.md

    r0688b5f r1c2dcba  
    77
    88### Hinzugefügt
     9- **Einen Beitrag im Fediverse melden.** Von einem Fediverse-Beitrag aus kannst du ihn jetzt den
     10  Moderatoren seines Heimatservers melden, mit optionaler Begründung.
    911- **Sprache eines Beitrags festlegen.** Wähle, in welcher Sprache du einen Beitrag geschrieben hast —
    1012  im Fediverse funktionieren damit der Sprachfilter der Timeline und die Übersetzen-Schaltfläche.
  • CHANGELOG.md

    r0688b5f r1c2dcba  
    77
    88### Added
     9- **Report a post to the fediverse.** From a fediverse post you can now report it to the moderators
     10  of its own home server, with an optional reason.
    911- **Set a post's language.** Choose the language you wrote a post in — on the fediverse it enables
    1012  timeline language filtering and the translate button.
  • CHANGELOG.nl.md

    r0688b5f r1c2dcba  
    77
    88### Toegevoegd
     9- **Rapporteer een post op de fediverse.** Vanaf een fediverse-post kun je die nu melden bij de
     10  moderators van de eigen server van die post, met een optionele reden.
    911- **Stel de taal van een post in.** Kies in welke taal je een post schreef — op de fediverse
    1012  werkt daarmee het taalfilter van de tijdlijn en de vertaal-knop.
  • src/routes/posts.js

    r0688b5f r1c2dcba  
    585585  const followed = !!req.query.followed;
    586586  const voted = !!req.query.voted;
     587  const reported = !!req.query.reported;
    587588  let target = null, followTarget = null;
    588   if (!sent && !followed && !voted && uri) {
     589  if (!sent && !followed && !voted && !reported && uri) {
    589590    try { target = await ActivityPubService.resolveRemoteNote(uri); } catch { /* ignore */ }
    590591    // Not a post? Maybe the URI is a profile/actor → offer Follow, not reply.
     
    600601    followed,
    601602    voted: !!req.query.voted,
     603    reported: !!req.query.reported,
    602604    liked: !!req.query.liked,
    603605    boosted: !!req.query.boosted,
     
    617619  if (site && uri && choice.length) { try { await ActivityPubService.voteOnRemotePoll(site, uri, choice.map(String)); } catch { /* ignore */ } }
    618620  res.redirect('/authorize_interaction?voted=1&uri=' + encodeURIComponent(uri));
     621});
     622
     623// 🚩 Report a remote post/account to its home instance (sends an AS2 Flag).
     624router.post('/authorize_interaction/report', requireSiteManager, async (req, res) => {
     625  const site = res.locals.site;
     626  const uri = (req.body.uri || '').toString();
     627  const actorUri = (req.body.actor_uri || '').toString();
     628  const reason = (req.body.reason || '').toString();
     629  if (site && (uri || actorUri)) { try { await ActivityPubService.sendReport(site, { objectUri: uri, actorUri, reason }); } catch { /* ignore */ } }
     630  res.redirect('/authorize_interaction?reported=1&uri=' + encodeURIComponent(uri || actorUri));
    619631});
    620632
  • src/services/ActivityPubService.js

    r0688b5f r1c2dcba  
    21942194}
    21952195
     2196// Report a remote post or account to its home instance (moderation). Sends the Mastodon-standard
     2197// AS2 `Flag`: object = [reported account, reported status?], content = the reason, delivered to the
     2198// reported account's inbox so their instance's moderators receive it. objectUri = a post URL (its
     2199// author is resolved + included) OR pass actorUri to report an account directly.
     2200export async function sendReport(site, { objectUri, actorUri, reason }) {
     2201  const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, '');
     2202  if (!base || !site || !site.slug) return { error: 'config' };
     2203  let targetActor = actorUri || null;
     2204  let noteUri = null;
     2205  if (objectUri && /^https?:\/\//i.test(objectUri)) {
     2206    const note = await apGetJson(objectUri).catch(() => null);
     2207    if (note && note.id) { noteUri = note.id; if (!targetActor) targetActor = actorUriOf(note.attributedTo); }
     2208    else if (!targetActor) return { error: 'not_found' };
     2209  }
     2210  if (!targetActor || !/^https?:\/\//i.test(targetActor)) return { error: 'not_found' };
     2211  const actor = await fetchActor(targetActor).catch(() => null);
     2212  const inbox = actor && (actor.inbox || (actor.endpoints && actor.endpoints.sharedInbox)); // personal inbox → their moderators
     2213  if (!inbox) return { error: 'unreachable' };
     2214  const me = actorId(base, site.slug);
     2215  const keys = getOrCreateKeys(site.slug);
     2216  const object = [targetActor];
     2217  if (noteUri && noteUri !== targetActor) object.push(noteUri);
     2218  const flag = {
     2219    '@context': AP_CONTEXT,
     2220    id: `${me}#report-${Date.now()}-${rid()}`,
     2221    type: 'Flag',
     2222    actor: me,
     2223    content: String(reason == null ? '' : reason).slice(0, 3000),
     2224    object, // [account, status?] — Mastodon's Flag shape
     2225    to: [targetActor],
     2226  };
     2227  deliverWithRetry(site.slug, inbox, flag, `${me}#main-key`, keys.private_pem);
     2228  return { ok: true };
     2229}
     2230
    21962231export function isBlockedAny(actorUri) {
    21972232  if (!actorUri) return false;
     
    22492284  listOutbox, deliverOutboxDelete, deliverOutboxUpdate,
    22502285  webfingerResolve, followActor, resolveRemoteActor, unfollowActor, listFollowing, setAutoBoost, backfillFromOutbox, getTimeline, sendInteraction, voteOnPoll, voteOnRemotePoll,
    2251   parseOwnPoll, pollTally, ownPollView, deliverPollUpdate, maybeCrawlThread,
     2286  parseOwnPoll, pollTally, ownPollView, deliverPollUpdate, maybeCrawlThread, sendReport,
    22522287  autoBoostCount, boostedCount, markBoosted, unmarkBoosted, markLiked, unmarkLiked, getTimelineReaction, upsertBoostedNote, getCirkelPosts, getCirkelMembers, selfHealTimeline,
    22532288  getNotifications, listBlocks, isBlockedAny, blockTarget, unblock,
  • src/services/i18n.js

    r0688b5f r1c2dcba  
    113113    'fedi.heading': 'Vanuit de fediverse', 'fedi.likes': 'sterren', 'fedi.boosts': 'boosts', 'fedi.replies': 'Reacties uit de fediverse',
    114114    'fedi.reply': 'Reageer', 'fedi.reply_ph': 'Je antwoord aan de fediverse…', 'fedi.send': 'Versturen', 'fedi.you': 'Jij',
    115     'fedi.remote_title': 'Reageer via de fediverse', 'fedi.follow_heading': 'Volgen via de fediverse', 'fedi.profile_follow': 'Volg via de fediverse', 'profile.since': 'Op Klonkt sinds', 'profile.free': 'Gratis', 'fedi.follow_intro': 'Je staat op het punt te volgen:', 'fedi.follow_btn': 'Volgen', 'fedi.cancel': 'Annuleren', 'fedi.followed_title': 'Volgverzoek verstuurd ✅', 'fedi.followed_done': 'Je volgverzoek is onderweg. Zodra de andere kant het accepteert, verschijnen hun berichten in je tijdlijn.', 'fedi.view_profile': 'Bekijk profiel →', 'fedi.remote_reply': 'Reageer via de fediverse', 'fedi.remote_prompt': 'Je fediverse-adres:', 'fedi.remote_notfound': 'Kon die post niet ophalen. Plak de volledige post-URL:', 'fedi.remote_load': 'Ophalen', 'fedi.remote_replying_to': 'Je reageert op', 'fedi.remote_as': 'Wordt verzonden als {site}.', 'fedi.remote_view_original': 'Bekijk de hele post + reacties op de bron →', 'fedi.remote_reply_short': 'via de fediverse', 'fedi.like_short': 'Like', 'fedi.unlike_short': 'Like intrekken', 'fedi.boost_short': 'Boost', 'fedi.remote_ph': 'jouw server', 'fedi.remote_sent_title': 'Verzonden ✅', 'fedi.remote_sent': 'Je reactie is verstuurd. Hij verschijnt zo bij de originele post op de fediverse, niet op deze pagina. Bekijk hem daar:', 'fedi.reply_where': 'Je reactie verschijnt bij de originele post op de fediverse, niet op deze pagina. Via de link hierboven zie je hem daar.', 'fedi.remote_back': '← Terug naar je site', 'fedi.like_btn': 'Like deze post', 'fedi.or_reply': 'of reageer:', 'fedi.liked_title': 'Geliket', 'fedi.liked_done': 'Je like is onderweg naar de fediverse.', 'fedi.boost_btn': 'Boost deze post', 'fedi.boosted_title': 'Geboost', 'fedi.boosted_done': 'Je boost is onderweg naar de fediverse.', 'fedi.remote_interact': 'Interageer via de fediverse', 'fedi.delete_confirm': 'Deze reactie verwijderen?', 'fedi.manage_title': 'Mijn fediverse-reacties', 'fedi.manage_empty': 'Je hebt nog geen reacties verstuurd.', 'fedi.goto_post': 'Naar de post', 'fedi.edit': 'Bewerken', 'fedi.save_edit': 'Opslaan', 'fedi.bm_label': 'Interageer via mijn site', 'fedi.bm_help': 'Sleep deze knop naar je bladwijzerbalk. Klik ’m daarna op elke fediverse-post (Mastodon, een andere Klonkt…) om er via jouw site op te reageren, te liken of te boosten.', 'tl.title': 'Krant', 'tl.lead': 'Volg accounts in de fediverse en zie hun berichten hier.', 'tl.follow_btn': 'Volgen', 'tl.following': 'Je volgt', 'tl.unfollow': 'Ontvolgen', 'tl.autoboost': 'Uitgelicht', 'tl.autoboost_follow': 'uitlichten in cirkel', 'tl.autoboost_hint': 'Hun nieuwe posts verschijnen doorlopend in jouw Cirkel (lokaal, geen fediverse-boost).', 'tl.pending': 'in afwachting', 'tl.unboost': 'Boost intrekken', 'tl.feed': 'Berichten', 'tl.tab_feed': 'Krant', 'tl.tab_following': 'Volgend', 'tl.tab_replies': 'Reacties', 'tl.empty_following': 'Je volgt nog niemand.', 'tl.empty': 'Nog niks — volg iemand om hun berichten hier te zien.', 'tl.view_original': 'Bekijk origineel →', 'tl.open_player': 'Open de speler', 'tl.paste_ph': 'Plak een fediverse-post-URL', 'tl.paste_go': 'Openen', 'tl.boosted': 'boostte dit', 'tl.read_more': 'Meer lezen', 'tl.show_less': 'Minder', 'poll.vote': 'Stem', 'poll.votes': 'stemmen', 'poll.closed': 'gesloten', 'poll.open': 'open', 'poll.aria': 'Peiling', 'poll.voter_one': 'stemmer', 'poll.voter_many': 'stemmers', 'poll.closes': 'sluit op', 'poll.multiple': 'meerkeuze', 'poll.fedi_only': 'Stemmen kan vanuit de fediverse — volg deze site en stem in je eigen app.', 'poll.voted_title': 'Stem verstuurd', 'poll.voted_done': 'Je stem is verstuurd naar de poll. De uitslag werkt bij zodra de maker die doorstuurt.',
     115    'fedi.remote_title': 'Reageer via de fediverse', 'fedi.follow_heading': 'Volgen via de fediverse', 'fedi.profile_follow': 'Volg via de fediverse', 'profile.since': 'Op Klonkt sinds', 'profile.free': 'Gratis', 'fedi.follow_intro': 'Je staat op het punt te volgen:', 'fedi.follow_btn': 'Volgen', 'fedi.cancel': 'Annuleren', 'fedi.followed_title': 'Volgverzoek verstuurd ✅', 'fedi.followed_done': 'Je volgverzoek is onderweg. Zodra de andere kant het accepteert, verschijnen hun berichten in je tijdlijn.', 'fedi.view_profile': 'Bekijk profiel →', 'fedi.remote_reply': 'Reageer via de fediverse', 'fedi.remote_prompt': 'Je fediverse-adres:', 'fedi.remote_notfound': 'Kon die post niet ophalen. Plak de volledige post-URL:', 'fedi.remote_load': 'Ophalen', 'fedi.remote_replying_to': 'Je reageert op', 'fedi.remote_as': 'Wordt verzonden als {site}.', 'fedi.remote_view_original': 'Bekijk de hele post + reacties op de bron →', 'fedi.remote_reply_short': 'via de fediverse', 'fedi.like_short': 'Like', 'fedi.unlike_short': 'Like intrekken', 'fedi.boost_short': 'Boost', 'fedi.remote_ph': 'jouw server', 'fedi.remote_sent_title': 'Verzonden ✅', 'fedi.remote_sent': 'Je reactie is verstuurd. Hij verschijnt zo bij de originele post op de fediverse, niet op deze pagina. Bekijk hem daar:', 'fedi.reply_where': 'Je reactie verschijnt bij de originele post op de fediverse, niet op deze pagina. Via de link hierboven zie je hem daar.', 'fedi.remote_back': '← Terug naar je site', 'fedi.like_btn': 'Like deze post', 'fedi.or_reply': 'of reageer:', 'fedi.liked_title': 'Geliket', 'fedi.liked_done': 'Je like is onderweg naar de fediverse.', 'fedi.boost_btn': 'Boost deze post', 'fedi.boosted_title': 'Geboost', 'fedi.boosted_done': 'Je boost is onderweg naar de fediverse.', 'fedi.remote_interact': 'Interageer via de fediverse', 'fedi.report_open': 'Deze post rapporteren', 'fedi.report_where': 'De melding gaat naar de server van {handle} (hun moderators).', 'fedi.report_ph': 'Wat is er mis? (optioneel)', 'fedi.report_send': 'Rapporteren', 'fedi.reported_title': 'Gerapporteerd', 'fedi.reported_done': 'Je melding is naar de server van de gebruiker gestuurd. Hun moderators bekijken het.', 'fedi.delete_confirm': 'Deze reactie verwijderen?', 'fedi.manage_title': 'Mijn fediverse-reacties', 'fedi.manage_empty': 'Je hebt nog geen reacties verstuurd.', 'fedi.goto_post': 'Naar de post', 'fedi.edit': 'Bewerken', 'fedi.save_edit': 'Opslaan', 'fedi.bm_label': 'Interageer via mijn site', 'fedi.bm_help': 'Sleep deze knop naar je bladwijzerbalk. Klik ’m daarna op elke fediverse-post (Mastodon, een andere Klonkt…) om er via jouw site op te reageren, te liken of te boosten.', 'tl.title': 'Krant', 'tl.lead': 'Volg accounts in de fediverse en zie hun berichten hier.', 'tl.follow_btn': 'Volgen', 'tl.following': 'Je volgt', 'tl.unfollow': 'Ontvolgen', 'tl.autoboost': 'Uitgelicht', 'tl.autoboost_follow': 'uitlichten in cirkel', 'tl.autoboost_hint': 'Hun nieuwe posts verschijnen doorlopend in jouw Cirkel (lokaal, geen fediverse-boost).', 'tl.pending': 'in afwachting', 'tl.unboost': 'Boost intrekken', 'tl.feed': 'Berichten', 'tl.tab_feed': 'Krant', 'tl.tab_following': 'Volgend', 'tl.tab_replies': 'Reacties', 'tl.empty_following': 'Je volgt nog niemand.', 'tl.empty': 'Nog niks — volg iemand om hun berichten hier te zien.', 'tl.view_original': 'Bekijk origineel →', 'tl.open_player': 'Open de speler', 'tl.paste_ph': 'Plak een fediverse-post-URL', 'tl.paste_go': 'Openen', 'tl.boosted': 'boostte dit', 'tl.read_more': 'Meer lezen', 'tl.show_less': 'Minder', 'poll.vote': 'Stem', 'poll.votes': 'stemmen', 'poll.closed': 'gesloten', 'poll.open': 'open', 'poll.aria': 'Peiling', 'poll.voter_one': 'stemmer', 'poll.voter_many': 'stemmers', 'poll.closes': 'sluit op', 'poll.multiple': 'meerkeuze', 'poll.fedi_only': 'Stemmen kan vanuit de fediverse — volg deze site en stem in je eigen app.', 'poll.voted_title': 'Stem verstuurd', 'poll.voted_done': 'Je stem is verstuurd naar de poll. De uitslag werkt bij zodra de maker die doorstuurt.',
    116116    'comments.to_start': 'om de conversatie te starten.',
    117117    'comments.reply': 'Reageer', 'comments.delete': 'Verwijder', 'comments.cancel': 'Annuleren',
     
    10371037    'fedi.heading': 'From the fediverse', 'fedi.likes': 'favourites', 'fedi.boosts': 'boosts', 'fedi.replies': 'Replies from the fediverse',
    10381038    'fedi.reply': 'Reply', 'fedi.reply_ph': 'Your reply to the fediverse…', 'fedi.send': 'Send', 'fedi.you': 'You',
    1039     'fedi.remote_title': 'Reply via the fediverse', 'fedi.follow_heading': 'Follow via the fediverse', 'fedi.profile_follow': 'Follow via the fediverse', 'profile.since': 'On Klonkt since', 'profile.free': 'Free', 'fedi.follow_intro': 'You are about to follow:', 'fedi.follow_btn': 'Follow', 'fedi.cancel': 'Cancel', 'fedi.followed_title': 'Follow request sent ✅', 'fedi.followed_done': 'Your follow request is on its way. Once accepted, their posts show up in your timeline.', 'fedi.view_profile': 'View profile →', 'fedi.remote_reply': 'Reply via the fediverse', 'fedi.remote_prompt': 'Your fediverse address:', 'fedi.remote_notfound': 'Could not fetch that post. Paste the full post URL:', 'fedi.remote_load': 'Fetch', 'fedi.remote_replying_to': 'Replying to', 'fedi.remote_as': 'Sent as {site}.', 'fedi.remote_view_original': 'View the full post + comments on the source →', 'fedi.remote_reply_short': 'via the fediverse', 'fedi.like_short': 'Like', 'fedi.unlike_short': 'Unlike', 'fedi.boost_short': 'Boost', 'fedi.remote_ph': 'your server', 'fedi.remote_sent_title': 'Sent ✅', 'fedi.remote_sent': 'Your reply has been sent. It will show up on the original post on the fediverse, not on this page. See it there:', 'fedi.reply_where': 'Your reply appears on the original post on the fediverse, not on this page. Use the link above to see it there.', 'fedi.remote_back': '← Back to your site', 'fedi.like_btn': 'Like this post', 'fedi.or_reply': 'or reply:', 'fedi.liked_title': 'Liked', 'fedi.liked_done': 'Your like is on its way to the fediverse.', 'fedi.boost_btn': 'Boost this post', 'fedi.boosted_title': 'Boosted', 'fedi.boosted_done': 'Your boost is on its way to the fediverse.', 'fedi.remote_interact': 'Interact via the fediverse', 'fedi.delete_confirm': 'Delete this reply?', 'fedi.manage_title': 'My fediverse replies', 'fedi.manage_empty': 'You have not sent any replies yet.', 'fedi.goto_post': 'Go to post', 'fedi.edit': 'Edit', 'fedi.save_edit': 'Save', 'fedi.bm_label': 'Interact via my site', 'fedi.bm_help': 'Drag this button to your bookmarks bar. Then click it on any fediverse post (Mastodon, another Klonkt…) to reply, like or boost it via your own site.', 'tl.title': 'News', 'tl.lead': 'Follow accounts on the fediverse and see their posts here.', 'tl.follow_btn': 'Follow', 'tl.following': 'Following', 'tl.unfollow': 'Unfollow', 'tl.autoboost': 'Featured', 'tl.autoboost_follow': 'feature in circle', 'tl.autoboost_hint': 'Their new posts keep showing in your Circle (local, no fediverse boost).', 'tl.pending': 'pending', 'tl.unboost': 'Unboost', 'tl.feed': 'Posts', 'tl.tab_feed': 'News', 'tl.tab_following': 'Following', 'tl.tab_replies': 'Replies', 'tl.empty_following': 'You do not follow anyone yet.', 'tl.empty': 'Nothing yet — follow someone to see their posts here.', 'tl.view_original': 'View original →', 'tl.open_player': 'Open the player', 'tl.paste_ph': 'Paste a fediverse post URL', 'tl.paste_go': 'Open', 'tl.boosted': 'boosted', 'tl.read_more': 'Read more', 'tl.show_less': 'Show less', 'poll.vote': 'Vote', 'poll.votes': 'votes', 'poll.closed': 'closed', 'poll.open': 'open', 'poll.aria': 'Poll', 'poll.voter_one': 'voter', 'poll.voter_many': 'voters', 'poll.closes': 'closes', 'poll.multiple': 'multiple choice', 'poll.fedi_only': 'Voting happens on the fediverse — follow this site and vote from your own app.', 'poll.voted_title': 'Vote sent', 'poll.voted_done': 'Your vote is on its way to the poll. The results refresh once the author sends the update.',
     1039    'fedi.remote_title': 'Reply via the fediverse', 'fedi.follow_heading': 'Follow via the fediverse', 'fedi.profile_follow': 'Follow via the fediverse', 'profile.since': 'On Klonkt since', 'profile.free': 'Free', 'fedi.follow_intro': 'You are about to follow:', 'fedi.follow_btn': 'Follow', 'fedi.cancel': 'Cancel', 'fedi.followed_title': 'Follow request sent ✅', 'fedi.followed_done': 'Your follow request is on its way. Once accepted, their posts show up in your timeline.', 'fedi.view_profile': 'View profile →', 'fedi.remote_reply': 'Reply via the fediverse', 'fedi.remote_prompt': 'Your fediverse address:', 'fedi.remote_notfound': 'Could not fetch that post. Paste the full post URL:', 'fedi.remote_load': 'Fetch', 'fedi.remote_replying_to': 'Replying to', 'fedi.remote_as': 'Sent as {site}.', 'fedi.remote_view_original': 'View the full post + comments on the source →', 'fedi.remote_reply_short': 'via the fediverse', 'fedi.like_short': 'Like', 'fedi.unlike_short': 'Unlike', 'fedi.boost_short': 'Boost', 'fedi.remote_ph': 'your server', 'fedi.remote_sent_title': 'Sent ✅', 'fedi.remote_sent': 'Your reply has been sent. It will show up on the original post on the fediverse, not on this page. See it there:', 'fedi.reply_where': 'Your reply appears on the original post on the fediverse, not on this page. Use the link above to see it there.', 'fedi.remote_back': '← Back to your site', 'fedi.like_btn': 'Like this post', 'fedi.or_reply': 'or reply:', 'fedi.liked_title': 'Liked', 'fedi.liked_done': 'Your like is on its way to the fediverse.', 'fedi.boost_btn': 'Boost this post', 'fedi.boosted_title': 'Boosted', 'fedi.boosted_done': 'Your boost is on its way to the fediverse.', 'fedi.remote_interact': 'Interact via the fediverse', 'fedi.report_open': 'Report this post', 'fedi.report_where': 'The report goes to the server of {handle} (their moderators).', 'fedi.report_ph': 'What is wrong? (optional)', 'fedi.report_send': 'Report', 'fedi.reported_title': 'Reported', 'fedi.reported_done': 'Your report has been sent to their server. Their moderators will review it.', 'fedi.delete_confirm': 'Delete this reply?', 'fedi.manage_title': 'My fediverse replies', 'fedi.manage_empty': 'You have not sent any replies yet.', 'fedi.goto_post': 'Go to post', 'fedi.edit': 'Edit', 'fedi.save_edit': 'Save', 'fedi.bm_label': 'Interact via my site', 'fedi.bm_help': 'Drag this button to your bookmarks bar. Then click it on any fediverse post (Mastodon, another Klonkt…) to reply, like or boost it via your own site.', 'tl.title': 'News', 'tl.lead': 'Follow accounts on the fediverse and see their posts here.', 'tl.follow_btn': 'Follow', 'tl.following': 'Following', 'tl.unfollow': 'Unfollow', 'tl.autoboost': 'Featured', 'tl.autoboost_follow': 'feature in circle', 'tl.autoboost_hint': 'Their new posts keep showing in your Circle (local, no fediverse boost).', 'tl.pending': 'pending', 'tl.unboost': 'Unboost', 'tl.feed': 'Posts', 'tl.tab_feed': 'News', 'tl.tab_following': 'Following', 'tl.tab_replies': 'Replies', 'tl.empty_following': 'You do not follow anyone yet.', 'tl.empty': 'Nothing yet — follow someone to see their posts here.', 'tl.view_original': 'View original →', 'tl.open_player': 'Open the player', 'tl.paste_ph': 'Paste a fediverse post URL', 'tl.paste_go': 'Open', 'tl.boosted': 'boosted', 'tl.read_more': 'Read more', 'tl.show_less': 'Show less', 'poll.vote': 'Vote', 'poll.votes': 'votes', 'poll.closed': 'closed', 'poll.open': 'open', 'poll.aria': 'Poll', 'poll.voter_one': 'voter', 'poll.voter_many': 'voters', 'poll.closes': 'closes', 'poll.multiple': 'multiple choice', 'poll.fedi_only': 'Voting happens on the fediverse — follow this site and vote from your own app.', 'poll.voted_title': 'Vote sent', 'poll.voted_done': 'Your vote is on its way to the poll. The results refresh once the author sends the update.',
    10401040    'comments.to_start': 'to start the conversation.',
    10411041    'comments.reply': 'Reply', 'comments.delete': 'Delete', 'comments.cancel': 'Cancel',
     
    19591959    'fedi.heading': 'Aus dem Fediverse', 'fedi.likes': 'Favoriten', 'fedi.boosts': 'Boosts', 'fedi.replies': 'Antworten aus dem Fediverse',
    19601960    'fedi.reply': 'Antworten', 'fedi.reply_ph': 'Deine Antwort an das Fediverse…', 'fedi.send': 'Senden', 'fedi.you': 'Du',
    1961     'fedi.remote_title': 'Über das Fediverse antworten', 'fedi.follow_heading': 'Über das Fediverse folgen', 'fedi.profile_follow': 'Über das Fediverse folgen', 'profile.since': 'Auf Klonkt seit', 'profile.free': 'Kostenlos', 'fedi.follow_intro': 'Du folgst gleich:', 'fedi.follow_btn': 'Folgen', 'fedi.cancel': 'Abbrechen', 'fedi.followed_title': 'Folge-Anfrage gesendet ✅', 'fedi.followed_done': 'Deine Folge-Anfrage ist unterwegs. Sobald sie akzeptiert wird, erscheinen ihre Beiträge in deiner Timeline.', 'fedi.view_profile': 'Profil ansehen →', 'fedi.remote_reply': 'Über das Fediverse antworten', 'fedi.remote_prompt': 'Deine Fediverse-Adresse:', 'fedi.remote_notfound': 'Beitrag konnte nicht geladen werden. Füge die vollständige Beitrags-URL ein:', 'fedi.remote_load': 'Laden', 'fedi.remote_replying_to': 'Antwort an', 'fedi.remote_as': 'Wird als {site} gesendet.', 'fedi.remote_view_original': 'Ganzen Beitrag + Kommentare an der Quelle ansehen →', 'fedi.remote_reply_short': 'übers Fediverse', 'fedi.like_short': 'Liken', 'fedi.unlike_short': 'Like zurücknehmen', 'fedi.boost_short': 'Boosten', 'fedi.remote_ph': 'dein Server', 'fedi.remote_sent_title': 'Gesendet ✅', 'fedi.remote_sent': 'Deine Antwort wurde gesendet. Sie erscheint gleich beim Originalbeitrag im Fediverse, nicht auf dieser Seite. Sieh sie dir dort an:', 'fedi.reply_where': 'Deine Antwort erscheint beim Originalbeitrag im Fediverse, nicht auf dieser Seite. Über den Link oben siehst du sie dort.', 'fedi.remote_back': '← Zurück zu deiner Seite', 'fedi.like_btn': 'Diesen Beitrag liken', 'fedi.or_reply': 'oder antworten:', 'fedi.liked_title': 'Geliked', 'fedi.liked_done': 'Dein Like ist unterwegs ins Fediverse.', 'fedi.boost_btn': 'Diesen Beitrag boosten', 'fedi.boosted_title': 'Geboostet', 'fedi.boosted_done': 'Dein Boost ist unterwegs ins Fediverse.', 'fedi.remote_interact': 'Übers Fediverse interagieren', 'fedi.delete_confirm': 'Diese Antwort löschen?', 'fedi.manage_title': 'Meine Fediverse-Antworten', 'fedi.manage_empty': 'Du hast noch keine Antworten gesendet.', 'fedi.goto_post': 'Zur Post', 'fedi.edit': 'Bearbeiten', 'fedi.save_edit': 'Speichern', 'fedi.bm_label': 'Über meine Seite interagieren', 'fedi.bm_help': 'Zieh diesen Button in deine Lesezeichenleiste. Klick ihn dann auf einem beliebigen Fediverse-Beitrag (Mastodon, ein anderes Klonkt…), um über deine eigene Seite zu antworten, zu liken oder zu boosten.', 'tl.title': 'Zeitung', 'tl.lead': 'Folge Konten im Fediverse und sieh ihre Beiträge hier.', 'tl.follow_btn': 'Folgen', 'tl.following': 'Du folgst', 'tl.unfollow': 'Entfolgen', 'tl.autoboost': 'Hervorgehoben', 'tl.autoboost_follow': 'im Zirkel hervorheben', 'tl.autoboost_hint': 'Ihre neuen Beiträge erscheinen laufend in deinem Zirkel (lokal, kein Fediverse-Boost).', 'tl.pending': 'ausstehend', 'tl.unboost': 'Boost zurücknehmen', 'tl.feed': 'Beiträge', 'tl.tab_feed': 'Zeitung', 'tl.tab_following': 'Folge ich', 'tl.tab_replies': 'Antworten', 'tl.empty_following': 'Du folgst noch niemandem.', 'tl.empty': 'Noch nichts — folge jemandem, um Beiträge hier zu sehen.', 'tl.view_original': 'Original ansehen →', 'tl.open_player': 'Player öffnen', 'tl.paste_ph': 'URL eines Fediverse-Beitrags einfügen', 'tl.paste_go': 'Öffnen', 'tl.boosted': 'hat geteilt', 'tl.read_more': 'Mehr lesen', 'tl.show_less': 'Weniger', 'poll.vote': 'Abstimmen', 'poll.votes': 'Stimmen', 'poll.closed': 'geschlossen', 'poll.open': 'offen', 'poll.aria': 'Umfrage', 'poll.voter_one': 'Teilnehmer', 'poll.voter_many': 'Teilnehmer', 'poll.closes': 'endet am', 'poll.multiple': 'Mehrfachauswahl', 'poll.fedi_only': 'Abstimmen geht über das Fediverse — folge dieser Seite und stimme in deiner eigenen App ab.', 'poll.voted_title': 'Stimme gesendet', 'poll.voted_done': 'Deine Stimme ist unterwegs zur Umfrage. Die Ergebnisse aktualisieren sich, sobald die Autorin oder der Autor das Update sendet.',
     1961    'fedi.remote_title': 'Über das Fediverse antworten', 'fedi.follow_heading': 'Über das Fediverse folgen', 'fedi.profile_follow': 'Über das Fediverse folgen', 'profile.since': 'Auf Klonkt seit', 'profile.free': 'Kostenlos', 'fedi.follow_intro': 'Du folgst gleich:', 'fedi.follow_btn': 'Folgen', 'fedi.cancel': 'Abbrechen', 'fedi.followed_title': 'Folge-Anfrage gesendet ✅', 'fedi.followed_done': 'Deine Folge-Anfrage ist unterwegs. Sobald sie akzeptiert wird, erscheinen ihre Beiträge in deiner Timeline.', 'fedi.view_profile': 'Profil ansehen →', 'fedi.remote_reply': 'Über das Fediverse antworten', 'fedi.remote_prompt': 'Deine Fediverse-Adresse:', 'fedi.remote_notfound': 'Beitrag konnte nicht geladen werden. Füge die vollständige Beitrags-URL ein:', 'fedi.remote_load': 'Laden', 'fedi.remote_replying_to': 'Antwort an', 'fedi.remote_as': 'Wird als {site} gesendet.', 'fedi.remote_view_original': 'Ganzen Beitrag + Kommentare an der Quelle ansehen →', 'fedi.remote_reply_short': 'übers Fediverse', 'fedi.like_short': 'Liken', 'fedi.unlike_short': 'Like zurücknehmen', 'fedi.boost_short': 'Boosten', 'fedi.remote_ph': 'dein Server', 'fedi.remote_sent_title': 'Gesendet ✅', 'fedi.remote_sent': 'Deine Antwort wurde gesendet. Sie erscheint gleich beim Originalbeitrag im Fediverse, nicht auf dieser Seite. Sieh sie dir dort an:', 'fedi.reply_where': 'Deine Antwort erscheint beim Originalbeitrag im Fediverse, nicht auf dieser Seite. Über den Link oben siehst du sie dort.', 'fedi.remote_back': '← Zurück zu deiner Seite', 'fedi.like_btn': 'Diesen Beitrag liken', 'fedi.or_reply': 'oder antworten:', 'fedi.liked_title': 'Geliked', 'fedi.liked_done': 'Dein Like ist unterwegs ins Fediverse.', 'fedi.boost_btn': 'Diesen Beitrag boosten', 'fedi.boosted_title': 'Geboostet', 'fedi.boosted_done': 'Dein Boost ist unterwegs ins Fediverse.', 'fedi.remote_interact': 'Übers Fediverse interagieren', 'fedi.report_open': 'Diesen Beitrag melden', 'fedi.report_where': 'Die Meldung geht an den Server von {handle} (deren Moderatoren).', 'fedi.report_ph': 'Was ist das Problem? (optional)', 'fedi.report_send': 'Melden', 'fedi.reported_title': 'Gemeldet', 'fedi.reported_done': 'Deine Meldung wurde an den Server der Person gesendet. Deren Moderatoren prüfen sie.', 'fedi.delete_confirm': 'Diese Antwort löschen?', 'fedi.manage_title': 'Meine Fediverse-Antworten', 'fedi.manage_empty': 'Du hast noch keine Antworten gesendet.', 'fedi.goto_post': 'Zur Post', 'fedi.edit': 'Bearbeiten', 'fedi.save_edit': 'Speichern', 'fedi.bm_label': 'Über meine Seite interagieren', 'fedi.bm_help': 'Zieh diesen Button in deine Lesezeichenleiste. Klick ihn dann auf einem beliebigen Fediverse-Beitrag (Mastodon, ein anderes Klonkt…), um über deine eigene Seite zu antworten, zu liken oder zu boosten.', 'tl.title': 'Zeitung', 'tl.lead': 'Folge Konten im Fediverse und sieh ihre Beiträge hier.', 'tl.follow_btn': 'Folgen', 'tl.following': 'Du folgst', 'tl.unfollow': 'Entfolgen', 'tl.autoboost': 'Hervorgehoben', 'tl.autoboost_follow': 'im Zirkel hervorheben', 'tl.autoboost_hint': 'Ihre neuen Beiträge erscheinen laufend in deinem Zirkel (lokal, kein Fediverse-Boost).', 'tl.pending': 'ausstehend', 'tl.unboost': 'Boost zurücknehmen', 'tl.feed': 'Beiträge', 'tl.tab_feed': 'Zeitung', 'tl.tab_following': 'Folge ich', 'tl.tab_replies': 'Antworten', 'tl.empty_following': 'Du folgst noch niemandem.', 'tl.empty': 'Noch nichts — folge jemandem, um Beiträge hier zu sehen.', 'tl.view_original': 'Original ansehen →', 'tl.open_player': 'Player öffnen', 'tl.paste_ph': 'URL eines Fediverse-Beitrags einfügen', 'tl.paste_go': 'Öffnen', 'tl.boosted': 'hat geteilt', 'tl.read_more': 'Mehr lesen', 'tl.show_less': 'Weniger', 'poll.vote': 'Abstimmen', 'poll.votes': 'Stimmen', 'poll.closed': 'geschlossen', 'poll.open': 'offen', 'poll.aria': 'Umfrage', 'poll.voter_one': 'Teilnehmer', 'poll.voter_many': 'Teilnehmer', 'poll.closes': 'endet am', 'poll.multiple': 'Mehrfachauswahl', 'poll.fedi_only': 'Abstimmen geht über das Fediverse — folge dieser Seite und stimme in deiner eigenen App ab.', 'poll.voted_title': 'Stimme gesendet', 'poll.voted_done': 'Deine Stimme ist unterwegs zur Umfrage. Die Ergebnisse aktualisieren sich, sobald die Autorin oder der Autor das Update sendet.',
    19621962    'comments.to_start': 'um das Gespräch zu starten.',
    19631963    'comments.reply': 'Antworten', 'comments.delete': 'Löschen', 'comments.cancel': 'Abbrechen',
  • src/views/pages/authorize-interaction.ejs

    r0688b5f r1c2dcba  
    9393      <a class="btn" href="/"><%= t('fedi.remote_back') %></a>
    9494    </p>
     95  <% } else if (typeof reported !== 'undefined' && reported) { %>
     96    <h1 class="auth-interact-title">🚩 <%= t('fedi.reported_title') %></h1>
     97    <p class="auth-interact-note"><%= t('fedi.reported_done') %></p>
     98    <p class="auth-interact-actions">
     99      <a class="btn" href="/"><%= t('fedi.remote_back') %></a>
     100    </p>
    95101  <% } else if (typeof voted !== 'undefined' && voted) { %>
    96102    <h1 class="auth-interact-title">📊 <%= t('poll.voted_title') %></h1>
     
    192198    </form>
    193199    <p class="auth-interact-note"><%= t('fedi.remote_as', { site: siteTitle }) %></p>
     200    <details class="auth-report">
     201      <summary>🚩 <%= t('fedi.report_open') %></summary>
     202      <form method="post" action="/authorize_interaction/report" class="auth-interact-form">
     203        <input type="hidden" name="uri" value="<%= uri %>">
     204        <input type="hidden" name="actor_uri" value="<%= target.actor_uri %>">
     205        <p class="auth-report-note"><%= t('fedi.report_where', { handle: target.actor_handle }) %></p>
     206        <textarea name="reason" rows="3" maxlength="3000" placeholder="<%= t('fedi.report_ph') %>"></textarea>
     207        <div class="auth-interact-actions">
     208          <button type="submit" class="btn btn-danger"><%= t('fedi.report_send') %></button>
     209        </div>
     210      </form>
     211    </details>
    194212  <% } %>
    195213  <% } %>
     
    291309  .auth-poll-pct { position: relative; z-index: 1; font-variant-numeric: tabular-nums; font-weight: 500; }
    292310  .auth-poll-foot { font-size: .82rem; color: var(--ink-soft, #888); margin: .1rem 0 0; }
     311  .auth-report { margin: .6rem 0 0; }
     312  .auth-report summary { cursor: pointer; font-size: .85rem; color: var(--ink-soft, #888); }
     313  .auth-report summary:hover, .auth-report[open] summary { color: #c0392b; }
     314  .auth-report[open] summary { margin-bottom: .5rem; }
     315  .auth-report-note { font-size: .82rem; color: var(--ink-muted, #999); margin: 0 0 .5rem; }
    293316</style>
    294317
  • test/activitypub-as2.test.js

    r0688b5f r1c2dcba  
    3232  'publicKey', 'owner', 'publicKeyPem',
    3333  'Note', 'Person', 'Create', 'Update', 'Delete', 'Tombstone', 'Announce', 'Like', 'Follow',
    34   'Accept', 'Reject', 'Undo', 'Add', 'Remove', 'Document', 'Image', 'Audio', 'Video',
     34  'Accept', 'Reject', 'Undo', 'Add', 'Remove', 'Flag', 'Document', 'Image', 'Audio', 'Video',
    3535  'Mention', 'Link', 'Collection', 'OrderedCollection', 'OrderedCollectionPage',
    3636]);
Note: See TracChangeset for help on using the changeset viewer.