Changeset f5c3870 in Klonkt for src/services/ActivityPubService.js
- Timestamp:
- 06/24/2026 04:08:34 PM (3 months ago)
- Branches:
- main
- Children:
- 19a72df
- Parents:
- d0cab9d
- File:
-
- 1 edited
-
src/services/ActivityPubService.js (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/services/ActivityPubService.js
rd0cab9d rf5c3870 364 364 // forged replies/likes/follows/timeline posts). GET/discovery stays open. 365 365 const claimedActor = typeof act.actor === 'string' ? act.actor : (act.actor && act.actor.id); 366 // Blocked actor/domain → silently drop (202, don't reveal the block). 367 if (claimedActor && isBlockedAny(claimedActor)) { console.log('[AP] inbox dropped (blocked)', claimedActor); return 202; } 366 368 const GATED = ['Create', 'Like', 'Announce', 'Follow', 'Delete', 'Undo', 'Accept', 'Reject']; 367 369 if (GATED.includes(type)) { … … 774 776 } 775 777 778 // ── Blocking / defederation ─────────────────────────────────────── 779 let _insBl, _delBl, _listBl; 780 function blStmts() { 781 if (!_insBl) { 782 _insBl = db.prepare('INSERT OR IGNORE INTO ap_blocks (slug, target, kind, label, created_at) VALUES (?,?,?,?,CURRENT_TIMESTAMP)'); 783 _delBl = db.prepare('DELETE FROM ap_blocks WHERE slug = ? AND target = ?'); 784 _listBl = db.prepare('SELECT * FROM ap_blocks WHERE slug = ? ORDER BY created_at DESC'); 785 } 786 return { ins: _insBl, del: _delBl, list: _listBl }; 787 } 788 export function listBlocks(slug) { return blStmts().list.all(slug); } 789 790 // True if an actor (or its whole domain) is blocked anywhere on this instance. 791 export function isBlockedAny(actorUri) { 792 if (!actorUri) return false; 793 let domain = ''; try { domain = new URL(actorUri).host; } catch { /* ignore */ } 794 try { return !!db.prepare("SELECT 1 FROM ap_blocks WHERE (kind='actor' AND target=?) OR (kind='domain' AND target=?) LIMIT 1").get(actorUri, domain); } 795 catch { return false; } 796 } 797 798 function purgeBlocked(kind, target) { 799 try { 800 if (kind === 'domain') { 801 const like = `%//${target}/%`; 802 db.prepare('DELETE FROM ap_interactions WHERE actor_uri LIKE ?').run(like); 803 db.prepare('DELETE FROM ap_timeline WHERE author_uri LIKE ?').run(like); 804 db.prepare('DELETE FROM ap_followers WHERE actor_uri LIKE ?').run(like); 805 } else { 806 db.prepare('DELETE FROM ap_interactions WHERE actor_uri = ?').run(target); 807 db.prepare('DELETE FROM ap_timeline WHERE author_uri = ?').run(target); 808 db.prepare('DELETE FROM ap_followers WHERE actor_uri = ?').run(target); 809 } 810 } catch { /* best-effort */ } 811 } 812 813 // Block an actor (@handle or actor URL) or a whole domain; purges their content. 814 export async function blockTarget(site, input) { 815 const raw = String(input || '').trim(); 816 if (!site || !site.slug || !raw) return { error: 'empty' }; 817 let kind, target, label; 818 if (/^https?:\/\//i.test(raw)) { kind = 'actor'; target = raw; label = raw; } 819 else if (raw.includes('@')) { 820 const actorUrl = await webfingerResolve(raw); 821 if (!actorUrl) return { error: 'not_found' }; 822 kind = 'actor'; target = actorUrl; label = raw.startsWith('@') ? raw : ('@' + raw); 823 } else { kind = 'domain'; target = raw.toLowerCase(); label = raw.toLowerCase(); } 824 blStmts().ins.run(site.slug, target, kind, label); 825 purgeBlocked(kind, target); 826 console.log('[AP] block', site.slug, kind, target); 827 return { ok: true, label }; 828 } 829 830 export function unblock(site, target) { blStmts().del.run(site.slug, target); return { ok: true }; } 831 776 832 export default { 777 833 getOrCreateKeys, apWants, sendAP, actorId, noteId, … … 781 837 listOutbox, deliverOutboxDelete, 782 838 webfingerResolve, followActor, unfollowActor, listFollowing, getTimeline, sendInteraction, 783 getNotifications, 839 getNotifications, listBlocks, isBlockedAny, blockTarget, unblock, 784 840 };
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)