v4: a handle with this instance's own host names the local user — another instance writes bob from here as bob@gerbeur.example, so a mention or a link copied from there named no one here: /@bob@gerbeur.example was a 404, and the mention notified nobody. localHandle (shared/validation.ts) drops this instance's host, its API's or its pages', from a handle; resolveUsername reads names by it, so the page, the API and the Open Graph 301 reach bob at /@bob, and so do the mention notifications and the chat's highlight and chime.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
khannurien
2026-10-09 22:11:39 +00:00
parent 6dfba07341
commit 9608520675
11 changed files with 79 additions and 12 deletions

View File

@@ -145,6 +145,7 @@ test("ogMiddleware: a former slug, a former name or another case gets a 301", as
[`/@OLD_NAME/dumps/now`, dump.path],
[`/@old_name/follow/playlists`, `/@${user.username}/follow/playlists`],
[`/@${user.username.toUpperCase()}`, `/@${user.username}`],
[`/@${user.username}@gerbeur.test/upvoted`, `/@${user.username}/upvoted`],
]
) {
const { res } = await handle(ogApp(), from);

View File

@@ -59,6 +59,8 @@ test("public profile: by @name in any case or id, without private fields", async
`/api/users/@${user.username}`,
`/api/users/@${user.username.toUpperCase()}`,
`/api/users/${user.id}`,
// As another instance writes them.
`/api/users/@${user.username}@gerbeur.test`,
]
) {
const res = await get<PublicUser>(path);
@@ -68,6 +70,10 @@ test("public profile: by @name in any case or id, without private fields", async
assertFalse("passwordHash" in res.data);
}
assertEquals((await get(`/api/users/@no_one_here`)).status, 404);
assertEquals(
(await get(`/api/users/@${user.username}@elsewhere.test`)).status,
404,
);
// Without the `@`, the key is an id.
assertEquals((await get(`/api/users/${user.username}`)).status, 404);
const me = await get<SelfUser>("/api/me", { auth: user.auth });

View File

@@ -15,6 +15,7 @@ test("mentions: notify the named, once per context, never the author or an email
const named = await createUser();
const { id: dumpId } = insertDump({ userId: author.id, title: "Topic" });
const body = `hi @${named.username.toUpperCase()} and @${named.username}, ` +
`@${named.username}@gerbeur.test as another instance writes them, ` +
`me @${author.username}, mail x@${named.username}.com, ` +
`[@${named.username}](link) @nobody_known`;
const c = await post<Comment>(`/api/dumps/${dumpId}/comments`, {