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:
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { mentionsUser } from "../../../utils/chat/text.ts";
|
||||
import { API_URL } from "../../../config/api.ts";
|
||||
|
||||
describe("mentionsUser", () => {
|
||||
test("case-insensitive whole-word match", () => {
|
||||
@@ -11,6 +12,14 @@ describe("mentionsUser", () => {
|
||||
expect(mentionsUser("[@alice](x)", "alice")).toBe(false);
|
||||
expect(mentionsUser("(@alice)", "alice")).toBe(false);
|
||||
});
|
||||
test("this instance's host, as another instance writes them, is them", () => {
|
||||
const host = new URL(API_URL).host;
|
||||
expect(mentionsUser(`hey @Alice@${host}`, "alice")).toBe(true);
|
||||
expect(mentionsUser("hey @alice@elsewhere.example", "alice")).toBe(false);
|
||||
expect(
|
||||
mentionsUser("hey @alice@elsewhere.example", "alice@elsewhere.example"),
|
||||
).toBe(true);
|
||||
});
|
||||
test("any of several mentions", () => {
|
||||
expect(mentionsUser("@bob @carol @alice", "alice")).toBe(true);
|
||||
});
|
||||
|
||||
@@ -10,6 +10,17 @@
|
||||
import { API_URL } from "../../config/api.ts";
|
||||
import { splitHandle } from "../../../shared/validation.ts";
|
||||
|
||||
/**
|
||||
* Checks whether `host`, as a handle writes it, is this instance's: its API's,
|
||||
* which handles carry, or its pages'. Another instance writes this one's users
|
||||
* with it.
|
||||
*/
|
||||
export function isSelfHost(host: string): boolean {
|
||||
const h = host.toLowerCase();
|
||||
return h === new URL(API_URL || location.origin).host ||
|
||||
h === location.host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the host of `handle`'s home instance, or undefined for a local
|
||||
* user.
|
||||
|
||||
@@ -5,12 +5,17 @@
|
||||
*/
|
||||
|
||||
import { mentionedUsernames } from "../../../shared/mention.ts";
|
||||
import { localHandle } from "../../../shared/validation.ts";
|
||||
import { isSelfHost } from "../auth/home.ts";
|
||||
|
||||
/**
|
||||
* Checks whether `body` @mentions `username`, ignoring case, with the pattern
|
||||
* the server uses for mention notifications. `WSProvider` uses it to pick the
|
||||
* chime, and `ChatModal` to highlight the message.
|
||||
* the server uses for mention notifications, this instance's own host
|
||||
* included (`localHandle`). `WSProvider` uses it to pick the chime, and
|
||||
* `ChatModal` to highlight the message.
|
||||
*/
|
||||
export function mentionsUser(body: string, username: string): boolean {
|
||||
return mentionedUsernames(body).includes(username.toLowerCase());
|
||||
return mentionedUsernames(body)
|
||||
.map((name) => localHandle(name, isSelfHost))
|
||||
.includes(username.toLowerCase());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user