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 type { Instance } from "@prisma/client";
|
||||||
import { client } from "~database/datasource";
|
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.
|
* Represents an instance in the database.
|
||||||
|
|
@ -15,32 +15,32 @@ export const addInstanceIfNotExists = async (
|
||||||
url: string,
|
url: string,
|
||||||
): Promise<Instance> => {
|
): Promise<Instance> => {
|
||||||
const origin = new URL(url).origin;
|
const origin = new URL(url).origin;
|
||||||
const hostname = new URL(url).hostname;
|
const host = new URL(url).host;
|
||||||
|
|
||||||
const found = await client.instance.findFirst({
|
const found = await client.instance.findFirst({
|
||||||
where: {
|
where: {
|
||||||
base_url: hostname,
|
base_url: host,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (found) return found;
|
if (found) return found;
|
||||||
|
|
||||||
// Fetch the instance configuration
|
// Fetch the instance configuration
|
||||||
const metadata = (await fetch(`${origin}/.well-known/lysand`).then((res) =>
|
const metadata = (await fetch(new URL("/.well-known/lysand", origin)).then(
|
||||||
res.json(),
|
(res) => res.json(),
|
||||||
)) as Partial<ServerMetadata>;
|
)) as Lysand.ServerMetadata;
|
||||||
|
|
||||||
if (metadata.type !== "ServerMetadata") {
|
if (metadata.type !== "ServerMetadata") {
|
||||||
throw new Error("Invalid instance metadata");
|
throw new Error("Invalid instance metadata (wrong type)");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(metadata.name && metadata.version)) {
|
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({
|
return await client.instance.create({
|
||||||
data: {
|
data: {
|
||||||
base_url: hostname,
|
base_url: host,
|
||||||
name: metadata.name,
|
name: metadata.name,
|
||||||
version: metadata.version,
|
version: metadata.version,
|
||||||
logo: metadata.logo,
|
logo: metadata.logo,
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import { addEmojiIfNotExists, emojiToAPI, emojiToLysand } from "./Emoji";
|
||||||
import { addInstanceIfNotExists } from "./Instance";
|
import { addInstanceIfNotExists } from "./Instance";
|
||||||
import { userRelations } from "./relations";
|
import { userRelations } from "./relations";
|
||||||
import { createNewRelationship } from "./Relationship";
|
import { createNewRelationship } from "./Relationship";
|
||||||
import { urlToContentFormat } from "@content_types";
|
import { getBestContentType, urlToContentFormat } from "@content_types";
|
||||||
|
|
||||||
export interface AuthData {
|
export interface AuthData {
|
||||||
user: UserWithRelations | null;
|
user: UserWithRelations | null;
|
||||||
|
|
@ -172,6 +172,14 @@ export const resolveUser = async (uri: string) => {
|
||||||
const userEmojis =
|
const userEmojis =
|
||||||
data.extensions?.["org.lysand:custom_emojis"]?.emojis ?? [];
|
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({
|
const user = await client.user.create({
|
||||||
data: {
|
data: {
|
||||||
username: data.username,
|
username: data.username,
|
||||||
|
|
@ -186,10 +194,20 @@ export const resolveUser = async (uri: string) => {
|
||||||
inbox: data.inbox,
|
inbox: data.inbox,
|
||||||
outbox: data.outbox,
|
outbox: data.outbox,
|
||||||
},
|
},
|
||||||
avatar: data.avatar?.[0].content || "",
|
emojis: {
|
||||||
header: data.header?.[0].content || "",
|
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 ?? "",
|
displayName: data.display_name ?? "",
|
||||||
note: data.bio?.[0].content ?? "",
|
note: getBestContentType(data.bio).content,
|
||||||
publicKey: data.public_key.public_key,
|
publicKey: data.public_key.public_key,
|
||||||
source: {
|
source: {
|
||||||
language: null,
|
language: null,
|
||||||
|
|
@ -199,33 +217,13 @@ export const resolveUser = async (uri: string) => {
|
||||||
fields: [],
|
fields: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
include: userRelations,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add to Meilisearch
|
// Add to Meilisearch
|
||||||
await addUserToMeilisearch(user);
|
await addUserToMeilisearch(user);
|
||||||
|
|
||||||
const emojis = [];
|
return user;
|
||||||
|
|
||||||
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,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -258,7 +256,6 @@ export const resolveWebFinger = async (identifier: string, host: string) => {
|
||||||
{
|
{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -76,8 +76,17 @@ export default apiRoute<{
|
||||||
|
|
||||||
if (!type || type === "accounts") {
|
if (!type || type === "accounts") {
|
||||||
// Check if q is matching format username@domain.com or @username@domain.com
|
// 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 accountMatches = q
|
||||||
const [username, domain] = q.trim().split("@");
|
?.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({
|
const account = await client.user.findFirst({
|
||||||
where: {
|
where: {
|
||||||
username,
|
username,
|
||||||
|
|
@ -98,7 +107,10 @@ export default apiRoute<{
|
||||||
|
|
||||||
if (resolve) {
|
if (resolve) {
|
||||||
const newUser = await resolveWebFinger(username, domain).catch(
|
const newUser = await resolveWebFinger(username, domain).catch(
|
||||||
() => null,
|
(e) => {
|
||||||
|
console.error(e);
|
||||||
|
return null;
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (newUser) {
|
if (newUser) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue