mirror of
https://github.com/versia-pub/server.git
synced 2026-01-26 12:16:01 +01:00
Make WebFinger resolve work
This commit is contained in:
parent
fcf952e1f3
commit
4acc04cd93
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue