Modify WebFinger behaviour, add user searching

This commit is contained in:
Jesse Wierzbinski 2024-04-09 18:22:57 -10:00
parent ae9698c647
commit d5817e985d
No known key found for this signature in database
6 changed files with 254 additions and 200 deletions

View file

@ -23,7 +23,7 @@ import { applicationToAPI } from "./Application";
import { attachmentToAPI, attachmentToLysand } from "./Attachment";
import { emojiToAPI, emojiToLysand, parseEmojis } from "./Emoji";
import type { UserWithRelations } from "./User";
import { fetchRemoteUser, parseMentionsUris, userToAPI } from "./User";
import { resolveUser, parseMentionsUris, userToAPI } from "./User";
import { statusAndUserRelations, userRelations } from "./relations";
const statusRelations = Prisma.validator<Prisma.StatusDefaultArgs>()({
@ -57,62 +57,9 @@ export const isViewableByUser = (status: Status, user: User | null) => {
return user && (status.mentions as User[]).includes(user);
};
export const fetchFromRemote = async (uri: string): Promise<Status | null> => {
// Check if already in database
/* const existingStatus: StatusWithRelations | null =
await client.status.findFirst({
where: {
uri: uri,
},
include: statusAndUserRelations,
});
if (existingStatus) return existingStatus;
const status = await fetch(uri);
if (status.status === 404) return null;
const body = (await status.json()) as LysandPublication;
const content = getBestContentType(body.contents);
const emojis = await parseEmojis(content?.content || "");
const author = await fetchRemoteUser(body.author);
let replyStatus: Status | null = null;
let quotingStatus: Status | null = null;
if (body.replies_to.length > 0) {
replyStatus = await fetchFromRemote(body.replies_to[0]);
}
if (body.quotes.length > 0) {
quotingStatus = await fetchFromRemote(body.quotes[0]);
}
return await createNewStatus({
account: author,
content: content?.content || "",
content_type: content?.content_type,
application: null,
// TODO: Add visibility
visibility: "public",
spoiler_text: body.subject || "",
uri: body.uri,
sensitive: body.is_sensitive,
emojis: emojis,
mentions: await parseMentionsUris(body.mentions),
reply: replyStatus
? {
status: replyStatus,
user: (replyStatus as StatusWithRelations).author,
}
: undefined,
quote: quotingStatus || undefined,
}); */
};
export const fetchFromRemote = async (
uri: string,
): Promise<StatusWithRelations | null> => {};
/**
* Return all the ancestors of this post,

View file

@ -128,7 +128,7 @@ export const followRequestUser = async (
return relationship;
};
export const fetchRemoteUser = async (uri: string) => {
export const resolveUser = async (uri: string) => {
// Check if user not already in database
const foundUser = await client.user.findUnique({
where: {
@ -228,6 +228,68 @@ export const fetchRemoteUser = async (uri: string) => {
});
};
/**
* Resolves a WebFinger identifier to a user.
* @param identifier Either a UUID or a username
*/
export const resolveWebFinger = async (identifier: string, host: string) => {
// Check if user not already in database
const foundUser = await client.user.findUnique({
where: {
username: identifier,
instance: {
base_url: host,
},
},
include: userRelations,
});
if (foundUser) return foundUser;
const hostWithProtocol = host.startsWith("http") ? host : `https://${host}`;
const response = await fetch(
new URL(
`/.well-known/webfinger?${new URLSearchParams({
resource: `acct:${identifier}@${host}`,
})}`,
hostWithProtocol,
),
{
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
},
);
const data = (await response.json()) as {
subject: string;
links: {
rel: string;
type: string;
href: string;
}[];
};
if (!data.subject || !data.links) {
throw new Error(
"Invalid WebFinger data (missing subject or links from response)",
);
}
const relevantLink = data.links.find((link) => link.rel === "self");
if (!relevantLink) {
throw new Error(
"Invalid WebFinger data (missing link with rel: 'self')",
);
}
return resolveUser(relevantLink.href);
};
/**
* Fetches the list of followers associated with the actor and updates the user's followers
*/