Skip to content

Commit 97bd437

Browse files
committed
Prepend Undo(Like) instead of restructuring Undo(Follow)
Reviewer noted that the chapter 22 Undo handler in the tutorial read very differently from the chapter 11 baseline because the Follow body had been wrapped in an if-block to share the listener with the new Like branch. Restructure the example so the Undo(Like) branch is prepended ahead of the original `if (!(object instanceof Follow)) return;` guard, leaving the Follow body untouched. The new branch `return`s on success so the guard never fires for Like objects. Addresses fedify-dev/fedify#731 (comment) Assisted-by: Claude Code:claude-opus-4-7
1 parent 0dcc8fe commit 97bd437

1 file changed

Lines changed: 23 additions & 24 deletions

File tree

server/federation.ts

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -207,30 +207,6 @@ federation
207207
})
208208
.on(Undo, async (ctx, undo) => {
209209
const object = await undo.getObject();
210-
// Undo(Follow): a remote follower has unfollowed alice; drop
211-
// the followers row keyed by the original follower's URI.
212-
if (object instanceof Follow) {
213-
if (undo.actorId == null || object.objectId == null) return;
214-
const target = ctx.parseUri(object.objectId);
215-
if (target?.type !== "actor") return;
216-
const localUser = (
217-
await db
218-
.select()
219-
.from(users)
220-
.where(eq(users.username, target.identifier))
221-
.limit(1)
222-
)[0];
223-
if (localUser === undefined) return;
224-
await db
225-
.delete(followers)
226-
.where(
227-
and(
228-
eq(followers.followingId, localUser.id),
229-
eq(followers.actorUri, undo.actorId.href),
230-
),
231-
);
232-
return;
233-
}
234210
// Undo(Like): a remote actor has retracted a like. Match by
235211
// the embedded Like's id (when the peer echoes the original)
236212
// or by (actor, object) since Pixelfed sometimes mints a
@@ -259,7 +235,30 @@ federation
259235
const matcher =
260236
conditions.length === 1 ? conditions[0] : or(...conditions);
261237
await db.delete(likes).where(matcher);
238+
return;
262239
}
240+
// Undo(Follow): a remote follower has unfollowed alice; drop
241+
// the followers row keyed by the original follower's URI.
242+
if (!(object instanceof Follow)) return;
243+
if (undo.actorId == null || object.objectId == null) return;
244+
const target = ctx.parseUri(object.objectId);
245+
if (target?.type !== "actor") return;
246+
const localUser = (
247+
await db
248+
.select()
249+
.from(users)
250+
.where(eq(users.username, target.identifier))
251+
.limit(1)
252+
)[0];
253+
if (localUser === undefined) return;
254+
await db
255+
.delete(followers)
256+
.where(
257+
and(
258+
eq(followers.followingId, localUser.id),
259+
eq(followers.actorUri, undo.actorId.href),
260+
),
261+
);
263262
})
264263
.on(Accept, async (_ctx, accept) => {
265264
// The remote server has accepted alice's outbound Follow.

0 commit comments

Comments
 (0)