Make WebFinger resolve work

This commit is contained in:
Jesse Wierzbinski 2024-04-09 19:13:13 -10:00
parent fcf952e1f3
commit 4acc04cd93
No known key found for this signature in database
3 changed files with 48 additions and 39 deletions

View file

@ -1,6 +1,6 @@
import type { Instance } from "@prisma/client";
import { client } from "~database/datasource";
import type { ServerMetadata } from "~types/lysand/Object";
import type * as Lysand from "lysand-types";
/**
* Represents an instance in the database.
@ -15,32 +15,32 @@ export const addInstanceIfNotExists = async (
url: string,
): Promise<Instance> => {
const origin = new URL(url).origin;
const hostname = new URL(url).hostname;
const host = new URL(url).host;
const found = await client.instance.findFirst({
where: {
base_url: hostname,
base_url: host,
},
});
if (found) return found;
// Fetch the instance configuration
const metadata = (await fetch(`${origin}/.well-known/lysand`).then((res) =>
res.json(),
)) as Partial<ServerMetadata>;
const metadata = (await fetch(new URL("/.well-known/lysand", origin)).then(
(res) => res.json(),
)) as Lysand.ServerMetadata;
if (metadata.type !== "ServerMetadata") {
throw new Error("Invalid instance metadata");
throw new Error("Invalid instance metadata (wrong type)");
}
if (!(metadata.name && metadata.version)) {
throw new Error("Invalid instance metadata");
throw new Error("Invalid instance metadata (missing name or version)");
}
return await client.instance.create({
data: {
base_url: hostname,
base_url: host,
name: metadata.name,
version: metadata.version,
logo: metadata.logo,

View file

@ -11,7 +11,7 @@ import { addEmojiIfNotExists, emojiToAPI, emojiToLysand } from "./Emoji";
import { addInstanceIfNotExists } from "./Instance";
import { userRelations } from "./relations";
import { createNewRelationship } from "./Relationship";
import { urlToContentFormat } from "@content_types";
import { getBestContentType, urlToContentFormat } from "@content_types";
export interface AuthData {
user: UserWithRelations | null;
@ -172,6 +172,14 @@ export const resolveUser = async (uri: string) => {
const userEmojis =
data.extensions?.["org.lysand:custom_emojis"]?.emojis ?? [];
const instance = await addInstanceIfNotExists(data.uri);
const emojis = [];
for (const emoji of userEmojis) {
emojis.push(await addEmojiIfNotExists(emoji));
}
const user = await client.user.create({
data: {
username: data.username,
@ -186,10 +194,20 @@ export const resolveUser = async (uri: string) => {
inbox: data.inbox,
outbox: data.outbox,
},
avatar: data.avatar?.[0].content || "",
header: data.header?.[0].content || "",
emojis: {
connect: emojis.map((emoji) => ({
id: emoji.id,
})),
},
instanceId: instance.id,
avatar: data.avatar
? Object.entries(data.avatar)[0][1].content
: "",
header: data.header
? Object.entries(data.header)[0][1].content
: "",
displayName: data.display_name ?? "",
note: data.bio?.[0].content ?? "",
note: getBestContentType(data.bio).content,
publicKey: data.public_key.public_key,
source: {
language: null,
@ -199,33 +217,13 @@ export const resolveUser = async (uri: string) => {
fields: [],
},
},
include: userRelations,
});
// Add to Meilisearch
await addUserToMeilisearch(user);
const emojis = [];
for (const emoji of userEmojis) {
emojis.push(await addEmojiIfNotExists(emoji));
}
const uriData = new URL(data.uri);
return await client.user.update({
where: {
id: user.id,
},
data: {
emojis: {
connect: emojis.map((emoji) => ({
id: emoji.id,
})),
},
instanceId: (await addInstanceIfNotExists(uriData.origin)).id,
},
include: userRelations,
});
return user;
};
/**
@ -258,7 +256,6 @@ export const resolveWebFinger = async (identifier: string, host: string) => {
{
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
},

View file

@ -76,8 +76,17 @@ export default apiRoute<{
if (!type || type === "accounts") {
// Check if q is matching format username@domain.com or @username@domain.com
if (q?.trim().match(/@?[a-zA-Z0-9_]+(@[a-zA-Z0-9_.:]+)/g)) {
const [username, domain] = q.trim().split("@");
const accountMatches = q
?.trim()
.match(/@?[a-zA-Z0-9_]+(@[a-zA-Z0-9_.:]+)/g);
if (accountMatches) {
// Remove leading @ if it exists
if (accountMatches[0].startsWith("@")) {
accountMatches[0] = accountMatches[0].slice(1);
}
const [username, domain] = accountMatches[0].split("@");
const account = await client.user.findFirst({
where: {
username,
@ -98,7 +107,10 @@ export default apiRoute<{
if (resolve) {
const newUser = await resolveWebFinger(username, domain).catch(
() => null,
(e) => {
console.error(e);
return null;
},
);
if (newUser) {