Changeset 8ad1784 in Klonkt
- Timestamp:
- 06/25/2026 09:08:20 PM (3 months ago)
- Branches:
- main
- Children:
- 7c62efb
- Parents:
- 4c12783
- Location:
- src
- Files:
-
- 4 edited
-
routes/posts.js (modified) (3 diffs)
-
services/ActivityPubService.js (modified) (3 diffs)
-
services/i18n.js (modified) (3 diffs)
-
views/pages/authorize-interaction.ejs (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/routes/posts.js
r4c12783 r8ad1784 485 485 const uri = (req.query.uri || '').toString(); 486 486 const sent = !!req.query.sent; 487 let target = null; 488 if (!sent) { try { target = await ActivityPubService.resolveRemoteNote(uri); } catch { /* ignore */ } } 487 const followed = !!req.query.followed; 488 let target = null, followTarget = null; 489 if (!sent && !followed && uri) { 490 try { target = await ActivityPubService.resolveRemoteNote(uri); } catch { /* ignore */ } 491 // Not a post? Maybe the URI is a profile/actor → offer Follow, not reply. 492 if (!target) { try { followTarget = await ActivityPubService.resolveRemoteActor(uri); } catch { /* ignore */ } } 493 } 489 494 renderPage(req, res, 'pages/authorize-interaction', { 490 495 pageTitle: 'Interacteer via de fediverse', … … 492 497 uri, 493 498 target, 499 followTarget, 494 500 sent, 501 followed, 495 502 liked: !!req.query.liked, 496 503 siteTitle: site ? site.title : '', … … 508 515 } 509 516 res.redirect('/authorize_interaction?liked=1&uri=' + encodeURIComponent(uri)); 517 }); 518 519 // Follow a remote actor from your own site (when the target is a profile, not a post). 520 router.post('/authorize_interaction/follow', requireSiteManager, (req, res) => { 521 const site = res.locals.site; 522 const uri = (req.body.uri || '').toString(); 523 if (site && uri) { 524 ActivityPubService.followActor(site, uri) 525 .catch((e) => console.warn('[AP] remote follow failed:', e.message)); 526 } 527 res.redirect('/authorize_interaction?followed=1&uri=' + encodeURIComponent(uri)); 510 528 }); 511 529 -
src/services/ActivityPubService.js
r4c12783 r8ad1784 1025 1025 const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, ''); 1026 1026 if (!base || !site || !site.slug) return { error: 'config' }; 1027 const actorUrl = await webfingerResolve(handle); 1027 // Accept either an @user@host handle (WebFinger) or a profile/actor URL directly 1028 // (the authorize_interaction Follow flow passes a URL). 1029 const s = String(handle || '').trim(); 1030 const actorUrl = /^https?:\/\//i.test(s) ? (safeUrl(s) || null) : await webfingerResolve(s); 1028 1031 if (!actorUrl) return { error: 'not_found' }; 1029 1032 const actor = await fetchActor(actorUrl).catch(() => null); … … 1039 1042 console.log('[AP] follow', site.slug, '→', actor.id); 1040 1043 return { ok: true, name: ai.name, handle: ai.handle }; 1044 } 1045 1046 // Resolve a profile URL or @handle to a followable remote actor (for the 1047 // authorize_interaction "Follow" flow). Returns display fields + inbox, or null 1048 // when it isn't a reachable actor (e.g. the input was a post, not a profile). 1049 export async function resolveRemoteActor(input) { 1050 const s = String(input || '').trim(); 1051 const actorUrl = /^https?:\/\//i.test(s) ? (safeUrl(s) || null) : await webfingerResolve(s); 1052 if (!actorUrl) return null; 1053 const actor = await fetchActor(actorUrl).catch(() => null); 1054 if (!actor || !actor.id || !actor.inbox) return null; 1055 const ai = actorInfo(actor, actor.id); 1056 return { actor_uri: actor.id, actor_name: ai.name, actor_handle: ai.handle, actor_url: ai.url, actor_icon: ai.icon, inbox: actor.inbox }; 1041 1057 } 1042 1058 … … 1162 1178 getInteractions, getInteractionById, buildReplyNote, getOutboxNote, deliverReply, resolveRemoteNote, 1163 1179 listOutbox, deliverOutboxDelete, 1164 webfingerResolve, followActor, unfollowActor, listFollowing, getTimeline, sendInteraction,1180 webfingerResolve, followActor, resolveRemoteActor, unfollowActor, listFollowing, getTimeline, sendInteraction, 1165 1181 getNotifications, listBlocks, isBlockedAny, blockTarget, unblock, 1166 1182 deliverWithRetry, enqueueDelivery, processDeliveryQueue, startDeliveryWorker, -
src/services/i18n.js
r4c12783 r8ad1784 109 109 'fedi.heading': 'Vanuit de fediverse', 'fedi.likes': 'sterren', 'fedi.boosts': 'boosts', 'fedi.replies': 'Reacties uit de fediverse', 110 110 'fedi.reply': 'Reageer', 'fedi.reply_ph': 'Je antwoord aan de fediverse…', 'fedi.send': 'Versturen', 'fedi.you': 'Jij', 111 'fedi.remote_title': 'Reageer via de fediverse', 'fedi. remote_reply': 'Reageer via de fediverse', 'fedi.remote_prompt': 'Je fediverse-adres (bv. @jij@mastodon.social):', '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.remote_ph': 'jouw server', 'fedi.remote_sent_title': 'Verzonden ✅', 'fedi.remote_sent': 'Je reactie is onderweg naar de fediverse en verschijnt zo bij de ontvanger.', '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.delete_confirm': 'Deze reactie verwijderen?', 'fedi.manage_title': 'Mijn fediverse-reacties', 'fedi.manage_empty': 'Je hebt nog geen reacties verstuurd.', 'tl.title': 'Tijdlijn', 'tl.lead': 'Volg accounts in de fediverse en zie hun berichten hier.', 'tl.follow_btn': 'Volgen', 'tl.following': 'Je volgt', 'tl.unfollow': 'Ontvolgen', 'tl.pending': 'in afwachting', 'tl.feed': 'Berichten', 'tl.empty': 'Nog niks — volg iemand om hun berichten hier te zien.', 'tl.view_original': 'Bekijk origineel →',111 'fedi.remote_title': 'Reageer via de fediverse', 'fedi.follow_heading': 'Volgen via de fediverse', 'fedi.follow_intro': 'Je staat op het punt te volgen:', 'fedi.follow_btn': 'Volgen', '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 (bv. @jij@mastodon.social):', '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.remote_ph': 'jouw server', 'fedi.remote_sent_title': 'Verzonden ✅', 'fedi.remote_sent': 'Je reactie is onderweg naar de fediverse en verschijnt zo bij de ontvanger.', '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.delete_confirm': 'Deze reactie verwijderen?', 'fedi.manage_title': 'Mijn fediverse-reacties', 'fedi.manage_empty': 'Je hebt nog geen reacties verstuurd.', 'tl.title': 'Tijdlijn', 'tl.lead': 'Volg accounts in de fediverse en zie hun berichten hier.', 'tl.follow_btn': 'Volgen', 'tl.following': 'Je volgt', 'tl.unfollow': 'Ontvolgen', 'tl.pending': 'in afwachting', 'tl.feed': 'Berichten', 'tl.empty': 'Nog niks — volg iemand om hun berichten hier te zien.', 'tl.view_original': 'Bekijk origineel →', 112 112 'comments.to_start': 'om de conversatie te starten.', 113 113 'comments.reply': 'Reageer', 'comments.delete': 'Verwijder', 'comments.cancel': 'Annuleren', … … 1118 1118 'fedi.heading': 'From the fediverse', 'fedi.likes': 'favourites', 'fedi.boosts': 'boosts', 'fedi.replies': 'Replies from the fediverse', 1119 1119 'fedi.reply': 'Reply', 'fedi.reply_ph': 'Your reply to the fediverse…', 'fedi.send': 'Send', 'fedi.you': 'You', 1120 'fedi.remote_title': 'Reply via the fediverse', 'fedi. remote_reply': 'Reply via the fediverse', 'fedi.remote_prompt': 'Your fediverse address (e.g. @you@mastodon.social):', '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.remote_ph': 'your server', 'fedi.remote_sent_title': 'Sent ✅', 'fedi.remote_sent': 'Your reply is on its way to the fediverse and will appear for the recipient shortly.', '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.delete_confirm': 'Delete this reply?', 'fedi.manage_title': 'My fediverse replies', 'fedi.manage_empty': 'You have not sent any replies yet.', 'tl.title': 'Timeline', 'tl.lead': 'Follow accounts on the fediverse and see their posts here.', 'tl.follow_btn': 'Follow', 'tl.following': 'Following', 'tl.unfollow': 'Unfollow', 'tl.pending': 'pending', 'tl.feed': 'Posts', 'tl.empty': 'Nothing yet — follow someone to see their posts here.', 'tl.view_original': 'View original →',1120 'fedi.remote_title': 'Reply via the fediverse', 'fedi.follow_heading': 'Follow via the fediverse', 'fedi.follow_intro': 'You are about to follow:', 'fedi.follow_btn': 'Follow', '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 (e.g. @you@mastodon.social):', '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.remote_ph': 'your server', 'fedi.remote_sent_title': 'Sent ✅', 'fedi.remote_sent': 'Your reply is on its way to the fediverse and will appear for the recipient shortly.', '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.delete_confirm': 'Delete this reply?', 'fedi.manage_title': 'My fediverse replies', 'fedi.manage_empty': 'You have not sent any replies yet.', 'tl.title': 'Timeline', 'tl.lead': 'Follow accounts on the fediverse and see their posts here.', 'tl.follow_btn': 'Follow', 'tl.following': 'Following', 'tl.unfollow': 'Unfollow', 'tl.pending': 'pending', 'tl.feed': 'Posts', 'tl.empty': 'Nothing yet — follow someone to see their posts here.', 'tl.view_original': 'View original →', 1121 1121 'comments.to_start': 'to start the conversation.', 1122 1122 'comments.reply': 'Reply', 'comments.delete': 'Delete', 'comments.cancel': 'Cancel', … … 2125 2125 'fedi.heading': 'Aus dem Fediverse', 'fedi.likes': 'Favoriten', 'fedi.boosts': 'Boosts', 'fedi.replies': 'Antworten aus dem Fediverse', 2126 2126 'fedi.reply': 'Antworten', 'fedi.reply_ph': 'Deine Antwort an das Fediverse…', 'fedi.send': 'Senden', 'fedi.you': 'Du', 2127 'fedi.remote_title': 'Über das Fediverse antworten', 'fedi. remote_reply': 'Über das Fediverse antworten', 'fedi.remote_prompt': 'Deine Fediverse-Adresse (z.B. @du@mastodon.social):', '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.remote_ph': 'dein Server', 'fedi.remote_sent_title': 'Gesendet ✅', 'fedi.remote_sent': 'Deine Antwort ist auf dem Weg ins Fediverse und erscheint gleich beim Empfänger.', '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.delete_confirm': 'Diese Antwort löschen?', 'fedi.manage_title': 'Meine Fediverse-Antworten', 'fedi.manage_empty': 'Du hast noch keine Antworten gesendet.', 'tl.title': 'Timeline', 'tl.lead': 'Folge Konten im Fediverse und sieh ihre Beiträge hier.', 'tl.follow_btn': 'Folgen', 'tl.following': 'Du folgst', 'tl.unfollow': 'Entfolgen', 'tl.pending': 'ausstehend', 'tl.feed': 'Beiträge', 'tl.empty': 'Noch nichts — folge jemandem, um Beiträge hier zu sehen.', 'tl.view_original': 'Original ansehen →',2127 'fedi.remote_title': 'Über das Fediverse antworten', 'fedi.follow_heading': 'Über das Fediverse folgen', 'fedi.follow_intro': 'Du folgst gleich:', 'fedi.follow_btn': 'Folgen', '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 (z.B. @du@mastodon.social):', '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.remote_ph': 'dein Server', 'fedi.remote_sent_title': 'Gesendet ✅', 'fedi.remote_sent': 'Deine Antwort ist auf dem Weg ins Fediverse und erscheint gleich beim Empfänger.', '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.delete_confirm': 'Diese Antwort löschen?', 'fedi.manage_title': 'Meine Fediverse-Antworten', 'fedi.manage_empty': 'Du hast noch keine Antworten gesendet.', 'tl.title': 'Timeline', 'tl.lead': 'Folge Konten im Fediverse und sieh ihre Beiträge hier.', 'tl.follow_btn': 'Folgen', 'tl.following': 'Du folgst', 'tl.unfollow': 'Entfolgen', 'tl.pending': 'ausstehend', 'tl.feed': 'Beiträge', 'tl.empty': 'Noch nichts — folge jemandem, um Beiträge hier zu sehen.', 'tl.view_original': 'Original ansehen →', 2128 2128 'comments.to_start': 'um das Gespräch zu starten.', 2129 2129 'comments.reply': 'Antworten', 'comments.delete': 'Löschen', 'comments.cancel': 'Abbrechen', -
src/views/pages/authorize-interaction.ejs
r4c12783 r8ad1784 27 27 <a class="btn btn-primary" href="/"><%= t('fedi.remote_back') %></a> 28 28 </p> 29 <% } else if (typeof followed !== 'undefined' && followed) { %> 30 <h1 class="auth-interact-title"><%= t('fedi.followed_title') %></h1> 31 <p class="auth-interact-note"><%= t('fedi.followed_done') %></p> 32 <p class="auth-interact-actions"> 33 <% if (uri) { %><a class="btn" href="<%= uri %>" rel="nofollow noopener"><%= t('fedi.view_profile') %></a><% } %> 34 <a class="btn btn-primary" href="/"><%= t('fedi.remote_back') %></a> 35 </p> 29 36 <% } else if (typeof sent !== 'undefined' && sent) { %> 30 37 <h1 class="auth-interact-title"><%= t('fedi.remote_sent_title') %></h1> … … 34 41 <a class="btn btn-primary" href="/"><%= t('fedi.remote_back') %></a> 35 42 </p> 43 <% } else if (typeof followTarget !== 'undefined' && followTarget) { %> 44 <h1 class="auth-interact-title"><%= t('fedi.follow_heading') %></h1> 45 <p class="auth-interact-meta"> 46 <%= t('fedi.follow_intro') %> 47 <a href="<%= followTarget.actor_url %>" rel="nofollow noopener" target="_blank"><strong><%= followTarget.actor_name %></strong></a> 48 <span class="fedi-handle"><%= followTarget.actor_handle %></span> 49 </p> 50 <form method="post" action="/authorize_interaction/follow" class="auth-interact-form"> 51 <input type="hidden" name="uri" value="<%= followTarget.actor_uri %>"> 52 <div class="auth-interact-actions"> 53 <button type="submit" class="btn btn-primary"><%= t('fedi.follow_btn') %></button> 54 <a href="/" class="btn"><%= t('comments.cancel') %></a> 55 </div> 56 </form> 57 <p class="auth-interact-note"><%= t('fedi.remote_as', { site: siteTitle }) %></p> 36 58 <% } else { %> 37 59 <h1 class="auth-interact-title"><%= t('fedi.remote_title') %></h1>
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)