fix(social): apply discover-equivalent filters to /api/social/search

Tombstoned users, replicated federated stubs, and users with
discoverable=0 were all surfacing in Add Friend search results.
Add the three WHERE filters that /api/social/discover already
applies. Federated users continue to be surfaced via the
client-side cross-instance fan-out in socialStore.searchUsers.

New tests: social.test.ts covers all five filter cases plus
existing self-exclusion and displayName-match behaviours.
This commit is contained in:
Jannis Braun
2026-04-25 18:42:05 +02:00
parent 9aa40c0304
commit b37d3bfa29
2 changed files with 179 additions and 8 deletions
+18 -8
View File
@@ -685,16 +685,26 @@ export async function socialRoutes(app: FastifyInstance): Promise<void> {
const pattern = `%${q}%`;
// Search by username or display name with partial matching, excluding current user
const conditions = [
eq(schema.users.isDeleted, 0),
eq(schema.users.discoverable, 1),
ne(schema.users.id, request.userId),
// Exclude replicated federated stubs — federated users are surfaced
// via the client-side cross-instance fan-out in
// packages/web/src/stores/socialStore.ts (searchUsers), which dedupes
// by canonical identity. Returning stubs here would be a noisy
// duplicate source AND would leak domain-suffix substring matches
// (stubs are stored as <homeUserId>@<domain>).
sql`(${schema.users.homeInstance} IS NULL OR ${schema.users.homeInstance} = '')`,
or(
like(schema.users.username, pattern),
like(schema.users.displayName, pattern),
)!,
];
const users = db.select()
.from(schema.users)
.where(and(
or(
like(schema.users.username, pattern),
like(schema.users.displayName, pattern)
),
ne(schema.users.id, request.userId)
))
.where(and(...conditions))
.limit(10)
.all();