Changeset d71ed03 in Klonkt
- Timestamp:
- 06/26/2026 09:28:16 AM (2 months ago)
- Branches:
- main
- Children:
- 355364c
- Parents:
- 1968592
- Location:
- src
- Files:
-
- 2 edited
-
server.js (modified) (2 diffs)
-
services/ActivityPubService.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/server.js
r1968592 rd71ed03 58 58 import ogRoutes from './routes/og.js'; 59 59 import apRoutes from './routes/activitypub.js'; 60 import { apWants, startDeliveryWorker } from './services/ActivityPubService.js';60 import { apWants, startDeliveryWorker, autoMigrateCircles } from './services/ActivityPubService.js'; 61 61 62 62 // SESSION_SECRET: use the env var if set. Otherwise auto-generate a strong one … … 161 161 startScheduler(); // release planning: publish scheduled posts when publish_at is reached 162 162 startDeliveryWorker(); // retry failed fediverse deliveries with backoff 163 autoMigrateCircles(); // one-time: convert legacy circle_links -> AP auto-boost follows 163 164 164 165 // Safety net: guarantee that there is always a primary site (solo/hub/circle). -
src/services/ActivityPubService.js
r1968592 rd71ed03 1054 1054 } 1055 1055 1056 // One-time, best-effort migration of the old Cirkels (pull-protocol circle_links) 1057 // into ActivityPub follows with auto-boost. Runs once per instance at boot so a 1058 // site that updates past the old protocol keeps its cirkel without a manual step. 1059 async function resolveApActor(siteUrl) { 1060 try { 1061 const r = await fetch(siteUrl, { headers: { Accept: 'application/activity+json' }, redirect: 'manual' }); 1062 // A Klonkt site's root 302s to /ap/users/<slug> (Location may be relative). 1063 if (r.status >= 300 && r.status < 400) { const loc = r.headers.get('location'); if (loc) return new URL(loc, siteUrl).href; } 1064 if (r.ok) return siteUrl; 1065 } catch { /* unreachable */ } 1066 return null; 1067 } 1068 let _circlesMigrating = false; 1069 export async function autoMigrateCircles() { 1070 if (_circlesMigrating) return; _circlesMigrating = true; 1071 try { 1072 let done; try { done = db.prepare('SELECT value FROM app_settings WHERE key = ?').get('circles_migrated_v1'); } catch { return; } 1073 if (done && done.value === '1') return; 1074 let links = []; 1075 try { links = db.prepare("SELECT cl.remote_url AS url, s.id AS sid, s.slug AS slug FROM circle_links cl JOIN sites s ON s.id = cl.local_site_id WHERE cl.status = 'active'").all(); } catch { /* no legacy table */ } 1076 let ok = 0; 1077 for (const l of links) { 1078 try { 1079 const actor = await resolveApActor(l.url); 1080 if (actor) { const r = await followActor({ id: l.sid, slug: l.slug }, actor, true); if (!(r && r.error)) ok++; } 1081 } catch { /* best-effort per link */ } 1082 } 1083 try { db.prepare('INSERT OR REPLACE INTO app_settings (key, value) VALUES (?, ?)').run('circles_migrated_v1', '1'); } catch { /* ignore */ } 1084 if (links.length) console.log(`[AP] circle migration: ${ok}/${links.length} legacy link(s) -> auto-boost`); 1085 } catch { /* never block boot */ } finally { _circlesMigrating = false; } 1086 } 1087 1056 1088 // Follow a fediverse account by @handle (WebFinger → actor → signed Follow). 1057 1089 export async function followActor(site, handle, autoBoost = false) { … … 1212 1244 listOutbox, deliverOutboxDelete, 1213 1245 webfingerResolve, followActor, resolveRemoteActor, unfollowActor, listFollowing, setAutoBoost, getTimeline, sendInteraction, 1214 autoBoostCount, getCirkelPosts, getCirkelMembers, 1246 autoBoostCount, getCirkelPosts, getCirkelMembers, autoMigrateCircles, 1215 1247 getNotifications, listBlocks, isBlockedAny, blockTarget, unblock, 1216 1248 deliverWithRetry, enqueueDelivery, processDeliveryQueue, startDeliveryWorker,
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)